【问题标题】:Is there any pythonic way to combine two dicts (making a list for common values)?是否有任何 pythonic 方式来组合两个 dicts(为常用值创建一个列表)?
【发布时间】:2014-04-06 09:34:07
【问题描述】:

例如,我有两个字典。

A = {'a':1, 'b':10, 'c':2}
B = {'b':3, 'c':4, 'd':10}

我想要这样的结果:

{'a':1, 'b': [10, 3], 'c':[2, 4], 'd':10}

如果一个键出现在两个字典中,我想列出这两个值。

【问题讨论】:

    标签: python python-2.7 dictionary


    【解决方案1】:

    我会制作所有个值列表:

    {k: filter(None, [A.get(k), B.get(k)]) for k in A.viewkeys() | B}
    

    使用dictionary view objects

    演示:

    >>> A = {'a':1, 'b':10, 'c':2}
    >>> B = {'b':3, 'c':4, 'd':10}
    >>> {k: filter(None, [A.get(k), B.get(k)]) for k in A.viewkeys() | B}
    {'a': [1], 'c': [2, 4], 'b': [10, 3], 'd': [10]}
    

    这至少让你的值类型保持一致。

    要生成输出,您需要使用两个字典之间的集合交集和对称差异:

    dict({k: [A[k], B[k]] for k in A.viewkeys() & B},
         **{k: A.get(k, B.get(k)) for k in A.viewkeys() ^ B})
    

    演示:

    >>> dict({k: [A[k], B[k]] for k in A.viewkeys() & B},
    ...      **{k: A.get(k, B.get(k)) for k in A.viewkeys() ^ B})
    {'a': 1, 'c': [2, 4], 'b': [10, 3], 'd': 10}
    

    在 Python 3 中,dict.keys() 是一个字典视图,因此您只需将所有 .viewkeys() 调用替换为 .keys() 即可获得相同的功能。

    【讨论】:

    • @thefourtheye:我的版本只调用了一次.get(),但确实不适用于A[k] = 0...哎呀。
    • @MartijnPieters 他们俩都是正确的。 1)如果我们做A.get(k, B.get(k)),我们无条件对他们两个都执行get,你的原始版本可以短路。 2)此外,您关于非真实价值观的观点是有效的。 +1 :)
    • @thefourtheye:不,我的版本不正确; A[k] = 0B 中没有这样的键导致 None 被用于输出。
    • @MartijnPieters 正确,这就是我的意思,你关于非真实价值观的观点是有效的。抱歉,不是很清楚。
    【解决方案2】:

    我会支持 Martijn Pieters 的概念,即您可能希望结果字典中的所有值都具有相同的类型。

    提供第二种选择:

    您也可以使用defaultdict 非常直观地实现您的结果。

    defaultdict 与 dict 类似,但它有一个默认构造函数,如果键不存在,则会调用该构造函数。

    所以你会去:

    from collections import defaultdict
    
    A = {'a':1, 'b':10, 'c':2}
    B = {'b':3, 'c':4, 'd':10}
    
    result = defaultdict(list)
    
    for d in [A, B]:
        for k, v in d.items():
            result[k].append(v)
    

    然后在稍后阶段,您仍然可以轻松地为结果添加更多值。

    你也可以切换到

    defaultdict(set)
    

    如果你不想重复值

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-18
      • 1970-01-01
      • 2022-08-18
      • 2021-10-19
      • 1970-01-01
      • 2011-08-15
      • 2011-09-26
      相关资源
      最近更新 更多