I would like to be able to make a Python dictionary with strings as keys and sets of strings as the values. E.g.: { "crackers" : ["crunchy", "salty"] }
It must be a set, not a list.
However, when I try the following:
word_dict = dict()
word_dict["foo"] = set()
word_dict["foo"] = word_dict["foo"].add("baz")
word_dict["foo"] = word_dict["foo"].add("bang")
I get:
Traceback (most recent call last):
File "process_input.py", line 56, in <module>
test()
File "process_input.py", line 51, in test
word_dict["foo"] = word_dict["foo"].add("bang")
AttributeError: 'NoneType' object has no attribute 'add'
If I do this:
word_dict = dict()
myset = set()
myset.add("bar")
word_dict["foo"] = myset
myset.add("bang")
word_dict["foo"] = myset
for key, value in word_dict:
print key,
print value
I get:
Traceback (most recent call last):
File "process_input.py", line 61, in <module>
test()
File "process_input.py", line 58, in test
for key, value in word_dict:
ValueError: too many values to unpack
Any tips on how to coerce Python into doing what I'd like? I'm an intermediate Python user (or so I thought, until I ran into this problem.)
The problem is this:
When you call
word_dict["foo"].add("baz")
, you're mutating the set thatword_dict["foo"]
refers to, and that operation returnsNone
. So reading your statement right to left, you're adding "baz" to the set refered to byword_dict["foo"]
, and then setting the result of that operation (that is,None
) toword_dict["foo"]
.So, to make this work as you expect, just remove
word_dict["foo"] =
from your statement.Dictionaries iterate on their keys by default, hence the ValueError you try this:
What's happening here is that iterating on word_dict is returning a key only (say, "foo"), which you're then trying to unpack into the variables
key
&value
. Unpacking "foo" gives you "f", "o", & "o", which is one value too many to fit into two variables, and hence your ValueError.As others have stated, what you want is to iterate on the dictionary's key-value pairs, like so:
When you say
word_dict["foo"].add("baz")
, you are adding 'baz' to the set word_dict["foo"].The function returns
None
-- updating the set is a side-effect. Soultimately sets
word_dict["foo"]
toNone
.Just
word_dict["foo"].add("baz")
would be correct.In the second scenario, when you say
you run into an error because the correct syntax is
to loop over just the keys in
word_dict
. In this situation, you wantinstead.
Try:
It looks like standard dictionary iterator returns only
key
but not tuple.Proof:
set.add()
does not return a newset
, it modifies theset
it is called on. Use it this way:Also, if you use a
for
loop to iterate over a dict, you are iterating over the keys:Alternatively you could iterate over
word_dict.items()
orword_dict.iteritems()
: