【问题标题】:python- searching dictionary sublists; converting dictionary keys to valuespython-搜索字典子列表;将字典键转换为值
【发布时间】:2015-07-17 21:12:28
【问题描述】:

假设我有以下字典(我正在使用的字典要大得多):

dict1={1:["item", "word", "thing"], 2:["word", "item"], 3:["thing", "item", "item"]}

并将字典中使用的每个单词都存储在一个列表中:

all_words=["item", "word", "thing"]

我想通过字典子列表运行列表中的每个单词,并返回找到它们的所有子列表的键,并将它们存储在元组中。所以我想得到:

dict2={"item":(1, 2, 3), "word":(1, 2), "thing":(1, 3)}

这就是我所拥有的:

dict2={}    
for word in all_words:
    for key, sublist in dict2.items():
        for word in sublist:
            if word not in sublist:
                dict2[word]=dict2[word]+key
            else:
                dict2[word]=key

【问题讨论】:

  • 那么问题出在哪里?
  • 我猜if word not in sublist: 应该是if word not in dict2:
  • 你为什么要遍历dict2.items()
  • 还有一个问题:dict2[word]+key 不起作用;您不能将tuple 添加到int。但是dict2[word] + (key,) 可以。当然,dict2[word] = (key,) 首先使它成为一个元组。如果你解决了这个问题,以及其他两个问题(提示:如果你给你的变量起比dict1更好的名字,那么犯这样的错误可能会更难),你的代码应该可以工作。但是,您可能希望查看 setdefault 方法和/或 defaultdict 类,以使其不那么冗长、更易于阅读、更难搞砸并且可能更高效。
  • 明确指出,您既不应该迭代dict2,也不应该迭代dict1.items()。你应该只迭代dict1

标签: python search dictionary sublist


【解决方案1】:

您的代码逻辑不正确,因为您正在迭代 3 个对象,而您只需要迭代字典并反转键和值的位置,但由于您可能有重复的值,您可以使用 set 容器来保存每个名称对应的键。 dict.setdefault 是解决这种情况的好工具:

>>> d={}
>>> for i,j in dict1.items():
...    for k in j:
...      d.setdefault(k,set()).add(i)
... 
>>> d
{'item': set([1, 2, 3]), 'word': set([1, 2]), 'thing': set([1, 3])}

【讨论】:

    【解决方案2】:

    所以,基于 cmets 的固定程序看起来像这样

    >>> dict2 = {}
    >>> for word in all_words:
    ...     # Iterate over the dict1's items
    ...     for key, sublist in dict1.items():
    ...         # If the word is found in the sublist
    ...         if word in sublist:
    ...             # If the current word is found in dict2's keys
    ...             if word in dict2:
    ...                 # Append the current key as a one element tuple
    ...                 dict2[word] += (key,)
    ...             else:
    ...                 # Create a one element tuple and assign it to the word
    ...                 dict2[word] = (key,)
    ... 
    >>> dict2
    {'item': (1, 2, 3), 'word': (1, 2), 'thing': (1, 3)}
    

    如果你知道字典理解,那么同样可以写成

    >>> {word: tuple(k for k, v in dict1.items() if word in v) for word in all_words}
    {'item': (1, 2, 3), 'word': (1, 2), 'thing': (1, 3)}
    

    基于每个对应worddict1 的整个元组创建逻辑已被压缩为单个生成器表达式并转换为带有tuple(k for k, v in dict1.items() if word in v) 的元组

    【讨论】:

      【解决方案3】:

      问题是你在循环dict2.items,而它应该是dict1.items。此外,如果找到,您不会将键 附加dict2 值中,您只需将值重新分配给在 dict1 值中找到的最后一个键。因此,dict2 的值不是您所期望的。

      您也可以选择使用collections.defaultdict(或使用@Kasra、@thefourtheye 的解决方案):

      from collections import defaultdict
      
      dict2 = defaultdict(tuple)
      
      for word in all_words:
          for key, sublist in dict1.iteritems(): # this 
              if word in sublist:
                  dict2[word] += (k,)
              else:
                  dict2[word] = (k,)
      
      dict2
      Out[3]: defaultdict(<type 'tuple'>, {'item': (1, 2, 3), 'word': (1, 2), 'thing': (1, 3)})
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-07-23
        • 1970-01-01
        • 2021-12-09
        • 1970-01-01
        • 2022-11-14
        • 2020-09-04
        • 2022-10-06
        相关资源
        最近更新 更多