【问题标题】:Merge dictionaries in different lists in Python在 Python 中合并不同列表中的字典
【发布时间】:2017-06-02 22:22:51
【问题描述】:

我需要将两个列表与其中的字典合并:

dict1 = [{'Count': '307', 'name': 'Other', 'Percentage': '7.7%'}, {'Count': '7,813', 'name': 'Other', 'Percentage': '6.8%'}...]
dict2 = [{'Place': 'Home'}, {'Place':'Forest'},...]

第一个列表(56 个字典)中有 56 个元素,第二个列表(dict2)中有 14 个元素。我想要做的是将dict2中的第一个元素插入到dict 1的前四个元素并重复该过程,直到dict1中的所有56个元素都具有{Place:x}。

所以最终我想要得到的是:

newdict = [{'Count': '307', 'name': 'Other', 'Percentage': '7.7%', 'Place': 'Home'}, {'Count': '7,813', 'name': 'Other', 'Percentage': '6.8%', 'Place':'Home'},{'Name': 'Other', 'Percentage': '6.6%', 'Place': 'Home', 'Count': '1,960'},{'Name': 'Other', 'Percentage': '7.6%', 'Place': 'Home', 'Count': '1,090'},{'Name': 'Other', 'Percentage': '7.6%', 'Place': 'Forest', 'Count': '1,090'} ]

等等..

dict2用尽时,它应该再次从第一个元素开始。

所以我更新了问题。我对这个问题的第一个看法是将 dict2 中相同键:值的数量增加到: dict2 = [{'Place': 'Home'}, {'Place':'Home'},{'Place':'Home'},{'Place':'Home'},{'Place':'Forest'},{'Place':'Forest'}...] 然后使用下面提到的相同方法来合并字典。但我相信应该有一种方法可以在不改变 dict2 的情况下做到这一点。

【问题讨论】:

  • 第二个列表用完后,第一个列表的第十五个元素应该怎么办?
  • 你的dict2只有14个元素,当我们处理`dict1中的第15个元素会发生什么?
  • 它应该再次从第一个元素(dict2)开始。
  • 你试过了吗?
  • dict1dict2 不是 lists 的好名字

标签: python dictionary


【解决方案1】:

如何简单地创建一个名为 result 的空字典,然后使用要合并的现有字典列表对其进行更新,例如:

def merge_dicts(*dict_args):
    """
    Given any number of dicts, shallow copy and merge into a new dict,
    precedence goes to key value pairs in latter dicts.
    :param dict_args: a list of dictionaries
    :return: dict - the merged dictionary
    """
    result = {}
    for dictionary in dict_args:
        result.update(dictionary)
    return result

【讨论】:

  • 谢谢你的回答,但这样我不会得到我想要的结果。我想要的是将列表 dict2 中的第一个字典更新为列表 dict1 中的前四个字典,然后将列表 dict2 中的第二个字典更新为列表 dict1 中的 4-8 个字典,依此类推。
【解决方案2】:

我们将使用zipitertools.cycle 将两个列表中的元素配对。

from itertools import cycle

for a, b in zip(dict1, cycle(dict2)):
    a.update(b)

如果不想修改原来的列表,那就稍微复杂一点。

from itertools import cycle, chain

new_list = [{k:v for k, v in chain(a.items(), b.items())} for a, b in zip(dict1, cycle(dict2))]

【讨论】:

  • 这改变了最初给定的字典,我不知道这是否是想要的行为。尽管如此 +1。
  • 如果你想建立一个新的列表...[dict(a,**b) for a, b in zip(dict1, cycle(dict2))]
  • @Chris_Rands 更好!我试过dict(**a, **b),但这在我使用的python版本上不起作用,所以我放弃了支持itertools
  • @PatrickHaugh 你能解释一下第二个脚本是如何工作的吗?我不明白 k:v for k, v in chain.from_iterable([a.items(), b.items()])} 做什么?它工作得很好,但我就是不明白如何。
  • @Extria 当然。这是一种字典理解,它是一种从现有数据构建字典的方法。 items 是一种字典方法,它以元组列表的形式返回键、值对。 chain.from_iterable 接受一个可迭代的子迭代(这里是一个列表列表)并产生第一个可迭代的所有元素,然后是第二个可迭代的所有元素。基本上,我们在这里所做的是将我们已有的两个字典放在一起制作一个新字典。
【解决方案3】:

使用模数:

new_list = []
x = len(dict2)
for v, item in enumerate(dict1):
    z = item.copy()
    z['Place'] = dict2[v % x]['Place']
    new_list.append(z)

【讨论】:

    【解决方案4】:

    你可以使用zip():

    res = []
    
    for i, j in zip(dict1, dict2):
        res.append(i)
        res[-1].update(j)
    

    如果您的dicts中的项目数不相同,您可以使用itertools.izip_longest()并将fillvalue参数设置为{}

    res = []
    
    for i, j in itertools.izip_longest(dict1, dict2, fillvalue={}):
        res.append(i)
        res[-1].update(j)
    

    【讨论】:

    • 列表理解怎么样:[dict(x,**y) for x,y in zip(dict1,dict2)]
    • @Chris_Rands 这是个不错的选择!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多