Python字典将字符串映射到字符串集合?

18
我想创建一个Python字典,以字符串为键,以字符串集合为值。例如:{ "crackers" : ["crunchy", "salty"] } 必须是一个集合,而不是列表。但是,当我尝试以下操作时:
  word_dict = dict()
  word_dict["foo"] = set()
  word_dict["foo"] = word_dict["foo"].add("baz")                                    
  word_dict["foo"] = word_dict["foo"].add("bang")

我得到:

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'

如果我这样做:

  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

我收到:

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

有没有关于如何强制Python按照我的意愿执行的技巧?我是一名中级Python用户(或者这样认为,直到遇到这个问题)。

5个回答

32

set.add() 不会返回一个新的 set,它会修改被调用的 set。使用方法如下:

word_dict = dict()
word_dict["foo"] = set()
word_dict["foo"].add("baz")                                    
word_dict["foo"].add("bang")

此外,如果你使用 for 循环来遍历一个字典,那么你遍历的是字典的键:

for key in word_dict:
   print key, word_dict[key]

或者,您可以迭代word_dict.items()word_dict.iteritems()

for key, value in word_dict.items():
   print key, value

31
from collections import defaultdict

word_dict = defaultdict(set)
word_dict['banana'].add('yellow')
word_dict['banana'].add('brown')
word_dict['apple'].add('red')
word_dict['apple'].add('green')
for key,values in word_dict.iteritems():
    print "%s: %s" % (key, values)

+1并没有直接回答问题,但肯定可以让提问者的生活更轻松。 - Chris Lutz
+1 不知道呢.. 我和楼主有一样的问题,这个方法非常好,而且我认为比被采纳的答案更易读。 - DrColossos
1
Python 3 将 dict.iteritems() 重命名为 dict.items() - zvi

7
当你说word_dict["foo"].add("baz")时,你正在将'baz'添加到集合word_dict["foo"]中。
该函数返回None -- 更新集合是一个副作用。因此,
word_dict["foo"] = word_dict["foo"].add("baz") 

最终将word_dict["foo"]设置为None

只有word_dict["foo"].add("baz")才是正确的。

在第二种情况下,当你说

for key, value in word_dict:                                                       

你遇到了一个错误,因为正确的语法是
for key in word_dict: 

如果您只想循环遍历word_dict中的键,可以采用以下方法。在这种情况下,您希望:

for key,value in word_dict.iteritems(): 

替代方案。


1

尝试:

word_dict = dict()
myset = set()
myset.add("bar")
word_dict["foo"] = myset
myset.add("bang")
word_dict["foo"] = myset

for key in word_dict:                                                       
    print key, word_dict[key]

看起来标准字典迭代器只返回 key 而不是元组。

证明:

>>> d = { 'test': 1 }
>>> for k, v in d: print k, v
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack
>>> for k in d: print d[k]
... 
1

另外,for key, value in word_dict.iteritems(): 虽然有点长,但在访问 keyvalue 方面更加友好。 - Chris Lutz

1
问题是这样的:
word_dict["foo"] = word_dict["foo"].add("baz")   

当您调用word_dict["foo"].add("baz")时,您正在改变word_dict["foo"]所引用的集合,并且该操作返回None。因此,从右到左阅读您的语句,您正在将"baz"添加到由word_dict["foo"]所引用的集合中,然后将该操作的结果(即None)设置为word_dict["foo"]
因此,要使此操作按预期工作,只需从语句中删除word_dict["foo"] =即可。
默认情况下,字典按其键进行迭代,因此在尝试执行此操作时会出现ValueError。
for key, value in word_dict: 

这里发生的是,对word_dict进行迭代返回的只是一个键(比如说“foo”),您尝试将其解包成变量keyvalue。解包“foo”会给您“f”,“o”和“o”,这是一个值过多以至于无法放入两个变量中,因此出现了ValueError。

正如其他人所说,您想要的是迭代字典的键-值对,像这样:

for key, value in word_dict.iteritems (): 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接