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”方式来获取我现在拥有的代码并将一个集合的内容“splat”为一个新集合,而不是将所有内容转换为冻结集合然后展平它?
编辑次数: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
谷歌搜索并没有完全解释这种情况。知道发生了什么事吗?
答案 0 :(得分:4)
您正在尝试以递归方式构建set
set
个。这是不允许的,因为set
是unhashable
,因此无法放入set
。您可以使用frozenset
,因为 可以播放。
try:
states = frozenset({nfa_eclosure(M, x+1) for x in xrange(len(M[s])) if M[s].get('')})
except IndexError:
states = frozenset([])
set
是无序的,正是因为它们是由其成员的散列在内部排序的。这允许快速查找集合成员。
答案 1 :(得分:1)
您正在尝试创建一组集。这不起作用,因为set不是可哈希类型,因为它是可变的,而sets只能包含hashable类型。这是因为Python使用集合中的项的哈希来快速检查成员资格。
您可以改为使用frozenset
。如果做不到这一点,请尝试list
。
答案 2 :(得分:0)
感谢大家的帮助。我很快就会接受答案。只想解释我遇到的另一个问题。 Apparently我在TypeError
看到的错误是一个错误。经过仔细检查,我试图迭代NoneType,字典不存在给定的密钥。我将默认设置为set([])
,现在一切都按预期运行。最终没有使用冷冻套装,但感谢您的解释!我很困惑。