gpt4 book ai didi

python - 使用特定键合并两个(或更多)字典配对列表

转载 作者:行者123 更新时间:2023-12-05 03:21:32 27 4
gpt4 key购买 nike

我有一组不同的字典列表(实际上是通过阅读 Excel 工作表获得的),我需要对它们进行“内部连接”:

  • 每个list相当于一个数据库表(每个dict是一条记录)
  • 每条记录都有一个保证在列表中唯一的特定键(列是“索引”)
  • 我需要生成另一个字典列表,其中每个字典都有一个给定的“索引”以及在“索引”匹配的所有列表中找到的所有其他键/值

举例说明:

a = [{'idx': 1, 'foo': 'xx1', 'bar': 'yy1'},
{'idx': 0, 'foo': 'xx0', 'bar': 'yy0'},
{'idx': 2, 'foo': 'xx2', 'bar': 'yy2'}]
b = [{'idx': 0, 'fie': 'zz0', 'fom': 'kk0'},
{'idx': 3, 'fie': 'zz3', 'fom': 'kk3'},
{'idx': 1, 'fie': 'zz1', 'fom': 'kk1'}]

我希望你有:

c = [{'idx': 0, 'foo': 'xx0', 'bar': 'yy0', 'fie': 'zz0', 'fom': 'kk0'},
{'idx': 1, 'foo': 'xx1', 'bar': 'yy1', 'fie': 'zz1', 'fom': 'kk1'},
{'idx': 2, 'foo': 'xx2', 'bar': 'yy2'},
{'idx': 3, 'fie': 'zz3', 'fom': 'kk3'}]

当然问题是各种列表可能有不同的长度并且不能很好地排序。

有没有一种简单的方法可以做到这一点,或者我应该明确地进行嵌套循环来搜索匹配的记录?

这确实有效,但我非常不确定这是“最 pythonic 的方式”:

a = [{'idx': 0, 'foo': 'xx0', 'bar': 'yy0'},
{'idx': 1, 'foo': 'xx1', 'bar': 'yy1'},
{'idx': 2, 'foo': 'xx2', 'bar': 'yy2'}]
b = [{'idx': 0, 'fie': 'zz0', 'fom': 'kk0'},
{'idx': 1, 'fie': 'zz1', 'fom': 'kk1'},
{'idx': 3, 'fie': 'zz3', 'fom': 'kk3'}]

c = [{'idx': 0, 'foo': 'xx0', 'bar': 'yy0', 'fie': 'zz0', 'fom': 'kk0'},
{'idx': 1, 'foo': 'xx1', 'bar': 'yy1', 'fie': 'zz1', 'fom': 'kk1'},
{'idx': 2, 'foo': 'xx2', 'bar': 'yy2'},
{'idx': 3, 'fie': 'zz3', 'fom': 'kk3'}]

li = [a, b]
t = [{z['idx']: z for z in w} for w in li]
r = {}
for k in t:
for j in k:
if j in r:
r[j].update(k[j])
else:
r[j] = k[j]
r = [t for t in r.values()]

print(r)
[{'idx': 0, 'foo': 'xx0', 'bar': 'yy0', 'fie': 'zz0', 'fom': 'kk0'}, {'idx': 1, 'foo': 'xx1', 'bar': 'yy1', 'fie': 'zz1', 'fom': 'kk1'}, {'idx': 2, 'foo': 'xx2', 'bar': 'yy2'}, {'idx': 3, 'fie': 'zz3', 'fom': 'kk3'}]

有人能想出更好的办法吗?

最佳答案

就算法而言,这与您的代码基本相同。您使用 O(1) 字典查找和更新以合并字典的想法是正确的。

from itertools import chain
from collections import defaultdict
from pprint import pprint

a = [{'idx': 1, 'foo': 'xx1', 'bar': 'yy1'},
{'idx': 0, 'foo': 'xx0', 'bar': 'yy0'},
{'idx': 2, 'foo': 'xx2', 'bar': 'yy2'}]
b = [{'idx': 0, 'fie': 'zz0', 'fom': 'kk0'},
{'idx': 3, 'fie': 'zz3', 'fom': 'kk3'},
{'idx': 1, 'fie': 'zz1', 'fom': 'kk1'}]

KEY = 'idx'
merged = defaultdict(dict)
for row in chain(a, b):
merged[row[KEY]].update(row)

pprint(list(merged.values()))

我尽量不使用任何单字母变量名(除了原始输入)
itertools.chain 让您可以将多个可迭代对象作为一个进行迭代
defaultdict 隐藏了一些“如果它已经在那里,就这样做,否则就那样做”
[x for x in iterable] 可以写成 list(iterable)
“合并”数据结构更有用。将它转储到一个低效的列表中是一种耻辱,但这是要求。

如果可能,您可以返回 merged.values(),这是一个可迭代的 View 对象 https://docs.python.org/3.7/library/stdtypes.html?highlight=dict%20values#dictionary-view-objects

顾虑:
这可以在数据库或 pandas 中处理,它们是为这个确切的功能而设计的。
如果行恰好在其中一个数据字段上发生冲突怎么办?您永远不会知道,因为更新只会覆盖。

关于python - 使用特定键合并两个(或更多)字典配对列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72952534/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com