[英]Pyhon - merging two list of dictionaries, only last dictionary in the second list returned
我尝试在 SO 中进行一些搜索以找到解决方案,但我仍然很难过。 我认为我从根本上误解了关于循环、列表和字典的一些东西。
我主要是自学成才,绝不是专家,所以如果这是一个非常愚蠢的问题,请提前道歉。
我有各种字典列表,例如下面的片段中的 l1 和 l2 示例。 我想要的 output 类似于
l3 = [{'A':1, 'B':4},{'A':2,'B':5},{'A':3,'B':6}
但是,无论我尝试什么,我似乎总是只从第二个字典中获取最后一个键值对,即
[{'A': 1, 'B': 6}, {'A': 2, 'B': 6}, {'A': 3, 'B': 6}]
这就是我所拥有的(评论来解释我认为代码是/应该做什么)
# First list of dictionaries
l1 = [{'A': 1},{'A': 2},{'A': 3}]
print(l1)
# Second list of dictionaries
l2 = [{'B': 4},{'B': 5},{'B': 6}]
print(l2)
# Empty list - to receive dictionaries in l1 and l2
l3 =[]
print(l3)
# Adding dictionaries from l1 into l3
for dict1 in l1:
l3.append(dict1)
print(l3)
# Opening l3 to loop through each dictionary, using range(len()) to loop through the index positions
for i in range(len(l3)):
# Opening l2 to loop through each dictionary
for dict2 in l2:
l3[i].update(dict2)
print(l3)
# Tried inverting the lists here, looping through l2 and then looping through l3 to append all dictionaries in l2
for dict2 in l2:
for i in range(len(l3)):
l3[i].update(dict2)
print(l3)
我还尝试使用 zip() 并最终得到一个字典元组列表,这让我觉得我要么使用不正确,要么它对于我需要的工具来说太复杂了。 根据我在做一些研究时的理解,问题是我一直在覆盖我刚刚写的值,我认为这就是为什么我总是最终只在所有地方添加最后一个值。
任何帮助表示赞赏!
您这里的代码不正确。 对于 l3 中的每个 dict,您更新 l2 中的每个 dict。
for i in range(len(l3)):
# Opening l2 to loop through each dictionary
for dict2 in l2:
l3[i].update(dict2)
尝试这个:
for i in range(len(l3)):
l3[i].update(l2[i])
这是一个更好的解决方案:如果第二个列表字典值具有相同的键,则它们将覆盖第一个。
result = list(map(lambda x,y:{**x, **y}, l1, l2))
这应该在一行代码中解决问题:
# First list of dictionaries
l1 = [{'A': 1},{'A': 2},{'A': 3}]
print(l1)
# Second list of dictionaries
l2 = [{'B': 4},{'B': 5},{'B': 6}]
print(l2)
# add dictionaries for dictionaries in zipped list1 and list2
l3 = [dict(d1, **d2) for d1, d2 in zip(l1, l2) ]
print(l3)
Output:
[{'A': 1}, {'A': 2}, {'A': 3}]
[{'B': 4}, {'B': 5}, {'B': 6}]
[{'A': 1, 'B': 4}, {'A': 2, 'B': 5}, {'A': 3, 'B': 6}]
你的第一个问题在这里:
# Adding dictionaries from l1 into l3
for dict1 in l1:
l3.append(dict1)
print(l3)
您正在复制对第一个列表中所有 dicts 的引用。 它们与您的第一个列表中的相同。 这意味着,编辑一个字典(比如调用update()
)会影响两个列表。
# Opening l3 to loop through each dictionary, using range(len()) to loop through the index positions
for i in range(len(l3)):
# Opening l2 to loop through each dictionary
for dict2 in l2:
l3[i].update(dict2)
print(l3)
# Tried inverting the lists here, looping through l2 and then looping through l3 to append all dictionaries in l2
for dict2 in l2:
for i in range(len(l3)):
l3[i].update(dict2)
print(l3)
在这里,您将循环两次。 l3
是l1
的副本,对于该列表中的每个项目,您使用l2
中每个项目的数据对其进行更新。 字典必须具有唯一键,因此每次更新键a
和b
时,它都会覆盖以前的值。
然后你基本上做同样的事情,但顺序不同。
你想要做什么它同时迭代每个列表中的字典,并从每个列表中的数据创建新的字典。 列表中每个位置的字典都有唯一的键,因此不会有任何覆盖。
l3 = [{**d1, **d2} for d1, d2 in zip(l1, l2)]
zip()
是正确的 function 在这里使用。 它从每个列表中取出一个项目并将它们作为一对交给您。 position i
的项目在一个列表和另一个列表中。
>>> print(list(zip(l1, l2)))
[({'A': 1}, {'B': 4}), ({'A': 2}, {'B': 5}), ({'A': 3}, {'B': 6})]
所以一旦你有了它,就从源字典创建一个新的字典。 如您所知{}
是新字典的语法,对变量执行**
意味着提取项目(键/值对)并将它们插入新字典。
另一个不那么 Pythonic,但对于新手来说可能更容易编写它的方式是这样的:
l3 = []
for d1, d2 in zip(l1, l2):
d3 = {}
d3.update(d1)
d3.update(d2)
l3.append(d3)
我希望您能欣赏第一个解决方案的简洁性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.