【问题标题】:Python dictionary that maps strings to a set of strings?将字符串映射到一组字符串的Python字典?
【发布时间】:2011-01-18 03:46:05
【问题描述】:

我希望能够制作一个 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 用户(或者我是这么认为的,直到我遇到这个问题。)

【问题讨论】:

    标签: python dictionary set


    【解决方案1】:

    set.add() 不会返回新的set,它会修改调用它的set。以这种方式使用它:

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

    此外,如果您使用 for 循环来迭代 dict,那么您就是在迭代键:

    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
    

    【讨论】:

      【解决方案2】:
      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 没有直接回答这个问题,但肯定可以让 OP 在这里的生活更轻松。
      • +1 不知道。我遇到了与 OP 相同的问题,这非常好,而且 IMO 比接受的答案更具可读性。
      • Python 3 重命名:dict.iteritems() 为:dict.items()
      【解决方案3】:

      当您说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(): 
      

      改为。

      【讨论】:

        【解决方案4】:

        试试:

        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 恕我直言的访问更好。
        【解决方案5】:

        问题是这样的:

        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 (): 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-08-21
          • 2021-05-09
          • 2021-11-15
          • 2012-01-23
          • 1970-01-01
          • 1970-01-01
          • 2023-03-26
          相关资源
          最近更新 更多