概念化集合理解

时间:2014-02-03 20:00:03

标签: python dictionary set set-comprehension

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

谷歌搜索并没有完全解释这种情况。知道发生了什么事吗?

3 个答案:

答案 0 :(得分:4)

您正在尝试以递归方式构建set set个。这是不允许的,因为setunhashable,因此无法放入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是无序的,正是因为它们是由其成员的散列在内部排序的。这允许快速查找集合成员。

阅读setshashable

的文档

答案 1 :(得分:1)

您正在尝试创建一组集。这不起作用,因为set不是可哈希类型,因为它是可变的,而sets只能包含hashable类型。这是因为Python使用集合中的项的哈希来快速检查成员资格。

您可以改为使用frozenset。如果做不到这一点,请尝试list

答案 2 :(得分:0)

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