【问题标题】:Python equivalent of zip for dictionariesPython 相当于 zip 的字典
【发布时间】:2013-05-03 17:25:42
【问题描述】:

如果我有这两个列表:

la = [1, 2, 3]
lb = [4, 5, 6]

我可以如下迭代它们:

for i in range(min(len(la), len(lb))):
    print la[i], lb[i]

或者更多的蟒蛇

for a, b in zip(la, lb):
    print a, b

如果我有两本字典怎么办?

da = {'a': 1, 'b': 2, 'c': 3}
db = {'a': 4, 'b': 5, 'c': 6}

同样,我可以手动迭代:

for key in set(da.keys()) & set(db.keys()):
    print key, da[key], db[key]

是否有一些内置方法可以让我进行如下迭代?

for key, value_a, value_b in common_entries(da, db):
    print key, value_a, value_b 

【问题讨论】:

  • @Eric python 内置插件通常是因为它们很受欢迎。这不是经常使用到使其成为内置

标签: python dictionary iterator


【解决方案1】:

没有内置函数或方法可以做到这一点。但是,您可以轻松定义自己的。

def common_entries(*dcts):
    if not dcts:
        return
    for i in set(dcts[0]).intersection(*dcts[1:]):
        yield (i,) + tuple(d[i] for d in dcts)

这建立在您提供的“手动方法”之上,但与 zip 一样,可用于任意数量的字典。

>>> da = {'a': 1, 'b': 2, 'c': 3}
>>> db = {'a': 4, 'b': 5, 'c': 6}
>>> list(common_entries(da, db))
[('c', 3, 6), ('b', 2, 5), ('a', 1, 4)]

当只提供一个字典作为参数时,它实际上返回dct.items()

>>> list(common_entries(da))
[('c', 3), ('b', 2), ('a', 1)]

没有字典,它返回一个空的生成器(就像zip()

>>> list(common_entries())
[]

【讨论】:

  • [Change1:] 另外,坚持zip(*seq)-->seq 合同,我建议返回key, (values, tuple, ...) 以便模仿字典。 [Change2:] 最后一个更好的名字是zipdic(*map)-->map
【解决方案2】:

dict.keys()返回的对象(称为字典键视图)acts like a set object,所以你可以只取键的intersection

da = {'a': 1, 'b': 2, 'c': 3, 'e': 7}
db = {'a': 4, 'b': 5, 'c': 6, 'd': 9}

common_keys = da.keys() & db.keys()

for k in common_keys:
    print(k, da[k], db[k])

在 Python 2 上,您需要自己将密钥转换为 sets:

common_keys = set(da) & set(db)

for k in common_keys:
    print k, da[k], db[k]

【讨论】:

    【解决方案3】:

    Dictionary key views 在 Python 3 中已经是 set-like 了。你可以删除 set():

    for key in da.keys() & db.keys():
        print(key, da[key], db[key])
    

    在 Python 2 中:

    for key in da.viewkeys() & db.viewkeys():
        print key, da[key], db[key]
    

    【讨论】:

      【解决方案4】:

      如果有人正在寻找通用解决方案:

      import operator
      from functools import reduce
      
      
      def zip_mappings(*mappings):
          keys_sets = map(set, mappings)
          common_keys = reduce(set.intersection, keys_sets)
          for key in common_keys:
              yield (key,) + tuple(map(operator.itemgetter(key), mappings))
      

      或者如果您想将键与值分开并使用类似的语法

      for key, (values, ...) in zip_mappings(...):
          ...
      

      我们可以用

      替换最后一行
      yield key, tuple(map(operator.itemgetter(key), mappings))
      

      测试

      from collections import Counter
      
      
      counter = Counter('abra')
      other_counter = Counter('kadabra')
      last_counter = Counter('abbreviation')
      for (character,
           frequency, other_frequency, last_frequency) in zip_mappings(counter,
                                                                       other_counter,
                                                                       last_counter):
          print('character "{}" has next frequencies: {}, {}, {}'
                .format(character,
                        frequency,
                        other_frequency,
                        last_frequency))
      

      给我们

      character "a" has next frequencies: 2, 3, 2
      character "r" has next frequencies: 1, 1, 1
      character "b" has next frequencies: 1, 1, 2
      

      (在Python 2.7.12Python 3.5.2 上测试)

      【讨论】:

        【解决方案5】:

        Python3:下面的怎么样?

        da = {'A': 1, 'b': 2, 'c': 3}
        db = {'B': 4, 'b': 5, 'c': 6}
        for key, (value_a, value_b) in  {k:(da[k],db[k]) for k in set(da)&set(db)}.items():
          print(key, value_a, value_b) 
        

        上面的 sn-p 打印公共键的值('b' 和 'c')并丢弃不匹配的键('A' 和 'B')。

        为了将所有键包含到输出中,我们可以使用稍微修改的理解:{k:(da.get(k),db.get(k)) for k in set(da)|set(db)}

        【讨论】:

        • 这更接近itertools.izip_longest,而不是zip。如所写,这给出了ValueError
        猜你喜欢
        • 1970-01-01
        • 2012-07-28
        • 1970-01-01
        • 2014-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-08
        相关资源
        最近更新 更多