0
def nfa_eclosure(M, s):
    """
    >>> M = [{'':{1,2,3}}, {'b':{1}}, {'a':{2}}]
    >>> nfa_eclosure(M, 0)
    set([0, 1, 2, 3])
    """
    try:
        states = {nfa_eclosure(M, x+1) for x in xrange(len(M[s])) if M[s].get('')}
    except IndexError:
        states = set([])
    states.add(s)
    return states

运行这个会抛出TypeError: unhashable type: 'set',但我看不到问题。


编辑:2014-02-03 15:25:00

谢谢大家的解释。这就说得通了。有没有一种“pythonic”的方式来获取我现在拥有的代码并将集合的内容“拼凑”到一个新的集合中,而不是将所有内容都转换为 freezeset 然后展平它?


编辑:2014-02-04 00:41:00

我做了一些修改,现在我想出了这个:

try:
    return set([s]).union(*(nfa_eclosure(M, x) for x in M[s].get('')))
except IndexError:
    return set([s])

但我有一个新的错误信息

TypeError: union() argument after * must be a sequence, not generator

谷歌搜索并不能很好地解释这种情况。知道发生了什么吗?

4

3 回答 3

5

您正在尝试以递归方式构建 a setof sets。这是不允许的,因为sets 是unhashable并且因此不能放在 a 中set。您可以使用 afrozenset因为它们是可散列的。

try:
    states = frozenset({nfa_eclosure(M, x+1) for x in xrange(len(M[s])) if M[s].get('')})
except IndexError:
    states = frozenset([])

sets 是无序的,正是因为它们在内部按其成员的哈希排序。这允许快速查找集合成员。

阅读有关集合和可散列的文档

于 2014-02-03T20:02:55.973 回答
1

您正在尝试制作一组​​套装。这是行不通的,因为集合不是可散列类型,因为它是可变的,并且集合只能包含可散列类型。这是因为 Python 使用集合中项目的哈希值来快速检查成员资格。

您可能可以使用 afrozenset代替。如果做不到这一点,请尝试list.

于 2014-02-03T20:03:28.183 回答
0

感谢大家的帮助。我很快就会接受答案。只是想解释我遇到的另一个问题。显然我看到的错误TypeError是一个错误。经过仔细检查,我试图用字典不存在给定键来迭代 NoneType 。我将默认设置为set([]),现在一切都按预期运行。最终没有选择冷冻套装,但感谢您的解释!我很困惑。

于 2014-02-04T06:50:30.307 回答