【问题标题】:Combining Dictionaries Of Lists In Python在 Python 中组合列表的字典
【发布时间】:2010-12-02 12:05:09
【问题描述】:

我有一个非常大的 (p, q) 元组集合,我想将它们转换为列表字典,其中每个元组中的第一项是索引包含 q 的列表的键。

例子:

Original List: (1, 2), (1, 3), (2, 3)  
Resultant Dictionary: {1:[2, 3], 2:[3]}  

此外,我想有效地组合这些字典。

例子:

Original Dictionaries: {1:[2, 3], 2:[3]}, {1:[4], 3:[1]}  
Resultant Dictionary: {1:[2, 3, 4], 2:[3], 3:[1]}  

这些操作位于一个内部循环中,因此我希望它们尽可能快。

提前致谢

【问题讨论】:

    标签: python list dictionary


    【解决方案1】:

    如果对元组列表进行排序,@gnibbler 建议的itertools.groupby 不是defaultdict 的一个不错的替代品,但它的使用方式需要与他建议的不同:

    import itertools
    import operator
    
    def lot_to_dict(lot):
      key = operator.itemgetter(0)
      # if lot's not sorted, you also need...:
      # lot = sorted(lot, key=key)
      # NOT in-place lot.sort to avoid changing it!
      grob = itertools.groupby(lot, key)
      return dict((k, [v[1] for v in itr]) for k, itr in grob)
    

    用于将列表的字典“合并”到新的 d.o.l...:

    def merge_dols(dol1, dol2):
      keys = set(dol1).union(dol2)
      no = []
      return dict((k, dol1.get(k, no) + dol2.get(k, no)) for k in keys)
    

    我给[] 一个昵称no 以避免无用地构造大量空列表,因为性能很重要。如果 dols 键的集合仅适度重叠,则更快的是:

    def merge_dols(dol1, dol2):
      result = dict(dol1, **dol2)
      result.update((k, dol1[k] + dol2[k])
                    for k in set(dol1).intersection(dol2))
      return result
    

    因为这仅对重叠键使用列表连接——所以,如果这些键很少,它会更快。

    【讨论】:

    • 2016 和 merge_dols v.1 听起来美妙而优雅,谢谢!但是,v.2 使用 non acceptable method: dict(dol1, **dol2)
    【解决方案2】:

    collections.defaultdict 是这样工作的:

    from collections import defaultdict
    dic = defaultdict(list)
    for i, j in tuples:
        dic[i].append(j)
    

    类似的字典:

    a, b = {1:[2, 3], 2:[3]}, {1:[4], 3:[1]}
    de = defaultdict(list, a)
    for i, j in b.items():
        de[i].extend(j)
    

    【讨论】:

      【解决方案3】:

      对救援不屑一顾(像往常一样)

      from collections import defaultdict
      my_dict = defaultdict(list)
      
      for key,value in original_list:
          my_dict[key].append(value)
      

      可以像这样组合两个字典(注意会保留重复的):

      for key,value in orig_dict:
          new_dict[key].extend(value)
      

      【讨论】:

      • 我认为你需要 .append() 元组中的项目。
      • 您的第二个循环无法运行
      【解决方案4】:

      这是迭代器的做法

      >>> mylist=[(1, 2), (1, 3), (2, 3)] >>> 从 itertools 导入 groupby >>> 从操作员导入 itemgetter >>> mylist=[(1, 2), (1, 3), (2, 3)] >>> groupby(mylist,itemgetter(0)) >>> 列表(_) [(1, ), (2, )]

      【讨论】:

      • 这不是 OP 要求的,是吗?
      【解决方案5】:

      我希望这些在一行中完成只是为了好玩:

      >>> from itertools import groupby
      >>> t=(1, 2), (1, 3), (2, 3) 
      >>> [(i,[x for _,x in list(f)]) for i,f in groupby(sorted(t),lambda t: t[0])] 
      [(1, [2, 3]), (2, [3])]
      >>> b={1:[2, 3], 2:[3]}, {1:[4], 3:[1]}
      >>> dict([(key,sum([i[1::][0] for i in elements],[])) for key,elements in groupby(sorted(b[0].items()+b[1].items()),lambda t: t[0])])
      {1: [2, 3, 4], 2: [3], 3: [1]}
      

      【讨论】:

        猜你喜欢
        • 2018-01-11
        • 2013-02-19
        • 2011-05-04
        • 1970-01-01
        • 2014-08-03
        • 1970-01-01
        • 1970-01-01
        • 2020-01-28
        • 2017-04-17
        相关资源
        最近更新 更多