用相同的键和值组合2个dict

2024-05-16 09:28:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用python词典,我想把它们结合起来。这些格言如下:

devices = [{'EUI':123,'Name':'gum 1'},{'EUI':456,'Name':'gum 2'},{'EUI':789,'Name':'gum 3'}]
data = [{'EUI':123,'data':111},{'EUI':456,'data':222},{'EUI':789,'data':333},{'EUI':456,'data':444},{'EUI':789,'data':555}]

它们的共同点是EUI(标识符)。我正在做的是使用一对循环并检查EUI是否相同。如果是相同的,我结合两个dict

最终的结果是,

[{'EUI': 123, 'data': 111, 'Name': 'gum 1'}, {'EUI': 456, 'data': 222, 'Name': 'gum 2'}, {'EUI': 789, 'data': 333, 'Name': 'gum 3'}, {'EUI': 456, 'data': 444, 'Name': 'gum 2'}, {'EUI': 789, 'data': 555, 'Name': 'gum 3'}]

我的完整代码如下:

devices = [{'EUI':123,'Name':'gum 1'},{'EUI':456,'Name':'gum 2'},{'EUI':789,'Name':'gum 3'}]
data = [{'EUI':123,'data':111},{'EUI':456,'data':222},{'EUI':789,'data':333},{'EUI':456,'data':444},{'EUI':789,'data':555}]

print(data)

for da in data:
  for dev in devices:
    if dev['EUI'] == da['EUI']:
      da.update(dev)
      break

print(data)

实际上,它工作得很好,但我认为它可能是一个更好的/更容易的/类似于pythonic的选项。有人知道另一种方法吗

多谢各位


Tags: nameindevfordata标识符dictda
3条回答

由于EUI在两个数据列表中似乎是唯一的,您可以立即使用字典,它将EUI映射到其他数据:

devices = {d.pop('EUI'): d for d in devices}
data = {d.pop('EUI'): d for d in data}

然后可以在EUI密钥上进行合并:

for k, d in data.items():
    d.update(devices.get(k, {}))

我考虑了len(set(d['EUI'] for d in devices) ^ set(d['EUI'] for d in data)) > 0的情况。
此方法保留原始的devicesdata

devices = [{'EUI': 123, 'Name': 'gum 1'}, {'EUI': 456, 'Name': 'gum 2'},
           {'EUI': 789, 'Name': 'gum 3'}]
data = [{'EUI': 123, 'data': 111}, {'EUI': 456, 'data': 222},
        {'EUI': 789, 'data': 333}]

device_dict = {
    device['EUI']: device
    for device in devices
}
results = [
    {**device_dict.pop(datum['EUI'], {}), **datum} for datum in data
] + list(device_dict.values())
print(results)

输出:

[{'EUI': 123, 'Name': 'gum 1', 'data': 111}, {'EUI': 456, 'Name': 'gum 2', 'data': 222}, {'EUI': 789, 'Name': 'gum 3', 'data': 333}]

说明:

  • device_dict = {...}:制作关于{}的{}键词典
  • [{**device_dict[datum['EUI']], **datum} for datum in data]:在循环数据时合并数据字典和设备字典
  • **device_dict.pop(datum['EUI'], {})而不是**device_dict[datum['EUI']]:考虑是否datum['EUI']不在device_dict。另外pop来自已处理的EUIs
  • + list(device_dict.values()):为device_dict的其余部分追加(仅在devices中的词典)

角落案例数据:

devices = [{'EUI': 123, 'Name': 'gum 1'}, {'EUI': 456, 'Name': 'gum 2'},
           {'EUI': 789, 'Name': 'gum 3'}, {'EUI': 888, 'Name': 'gum 4'}]
data = [{'EUI': 123, 'data': 111}, {'EUI': 456, 'data': 222},
        {'EUI': 789, 'data': 333}, {'EUI': 777, 'data': 444}]

输出:

[{'EUI': 123, 'Name': 'gum 1', 'data': 111}, {'EUI': 456, 'Name': 'gum 2', 'data': 222}, {'EUI': 789, 'Name': 'gum 3', 'data': 333}, {'EUI': 777, 'data': 444}, {'EUI': 888, 'Name': 'gum 4'}]

from itertools import zip_longest

result = [{**u, **v} for u, v in zip_longest(data, devices, fillvalue={})] print(result)

相关问题 更多 >