Conceptualizing 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

Running this throws TypeError: unhashable type: 'set'but I can't see the problem.


Edit: 2014-02-03 15:25:00

Thanks for the explanations everyone. That makes sense. Is there a "pythonic" way to take the code I have now and "splat" the contents of a set into a new set, rather than convert everything to a frozenset and then flatten it?


Edit: 2014-02-04 00:41:00

I made some modifications and now I came up with this:

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

but I have a new error message

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

A google search didn't exactly explain the situation too well. Know what's going on?

Answers


You're trying to build a set of sets, recursively. This is not allowed because sets are unhashable and therefore cannot be placed in a set. You can use a frozenset because they are hashable.

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

sets are unordered, precisely because they are ordered internally by the hash of their members. This allows for fast lookup of set members.

Read up on the docs for sets and hashable


You are trying to make a set of sets. This won't work, because a set is not a hashable type, as it is mutable, and sets can only contain hashable types. This is because Python uses the hashes of items in a set to quickly check for membership.

You might able to use a frozenset instead. Failing that, try a list.


Thanks for the help everyone. I'll get to accepting an answer shortly. Just wanted to explain the other issue I was having. Apparently the error I was seeing with TypeError was a bug. Upon closer inspection, I was trying to iterate of NoneType with the given key didn't exist for the dictionary. I set the default to set([]) and now everything runs as expected. Didn't end up going with the frozen set, but thanks for explaining it! I was so confused.


Need Your Help

light-symbol.el to only light matching symbol's background and not refontify it

emacs elisp

I use light-symbol.el to show matching symbols on the page to where the cursor is at. It has been working very well except that it completely strips the matching symbols from their original color s...

Asp.Net how to integrate Video Chat

c# ajax videochat

I am developing a video chat website application for a social networking website, like if i am broadcasting video, the video will be viewed by n number of users.