代码之家  ›  专栏  ›  技术社区  ›  Jason Coon

将此Python结构的值合并到单个字典中的更快方法是什么?

  •  3
  • Jason Coon  · 技术社区  · 16 年前

    all_classes

    我有一本字典,像这样:

    groups_and_classes = {'group_1': {'class_A': [1, 2, 3],
                                      'class_B': [1, 3, 5, 7], 
                                      'class_c': [1, 2], # ...many more items like this
                                     },
                          'group_2': {'class_A': [11, 12, 13],
                                      'class_C': [5, 6, 7, 8, 9]
                                     }, # ...and many more items like this
                         }
    

    函数从中创建新对象 groups_and_classes 像这样(创建这个的函数经常被调用):

    all_classes = {'class_A': [1, 2, 3, 11, 12, 13],
                   'class_B': [1, 3, 5, 7, 9],
                   'class_C': [1, 2, 5, 6, 7, 8, 9]
                  }
    

    现在,有一个循环是这样做的:

    all_classes = {}
    for group in groups_and_classes.values():
        for c, vals in group.iteritems():
            for v in vals:
                if all_classes.has_key(c):
                    if v not in all_classes[c]:
                        all_classes[c].append(v)
                else:
                    all_classes[c] = [v]
    

    到目前为止,我把代码改成使用 set list 因为名单的顺序无关紧要 值必须是唯一的:

    all_classes = {}
    for group in groups_and_classes.values():
        for c, vals in group.iteritems():
            try:
                all_classes[c].update(set(vals))
            except KeyError:
                all_classes[c] = set(vals)
    

    所有课程

    问题 :有没有更有效的方法 (除了同时建造外 是构建的,并且在调用此函数的任何地方都会发生更改)?

    3 回复  |  直到 16 年前
        1
  •  4
  •   Vicki Laidler    16 年前

    from collections import defaultdict
    all_classes = defaultdict(set)
    for group in groups_and_classes.values():
        for c, vals in group.iteritems():
            all_classes[c].update(set(vals))
    

    自切片面包以来,默认dicts并不是最棒的东西,但它们很酷

        2
  •  2
  •   Brian    16 年前

    有一件事可能会稍微改善,那就是避免到集合的冗余转换,只需使用:

    all_classes[c].update(vals)
    

    update 实际上可以采用任意iterable,因为它本质上只是迭代和相加,所以可以避免额外的转换步骤。

        3
  •  2
  •   Community Mohan Dere    9 年前

    Combining Dictionaries Of Lists In Python .

    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
    
    g1 = groups_and_classes['group_1']
    g2 = groups_and_classes['group_2']
    
    all_classes = merge_dols(g1,g2)
    

    或

    all_classes = reduce(merge_dols,groups_and_classes.values())
    

    --复制自 Alex Martelli

    itertools.reduce

    all\u classes=reduce(合并\u dols、groups\u和\u classes.values())