简体   繁体   English

如何通过使用唯一值安全地合并 Python 中的嵌套列表?

[英]How can I safely merge a nested list in Python by use a unique value?

I have a nested list (list of list) and I want to merge if id from nested list is duplicates: Like :我有一个嵌套列表(列表列表),如果嵌套列表中的 id 重复,我想合并:例如:

[
  {'id': 2404, 'interfaces': [{'port': 78, 'module': 1 }]}
  {'id': 2404, 'interfaces': [{'port': 79, 'module': 1 }]} 
  {'id': 1234, 'interfaces': [{'port': 79, 'module': 1 }]} 
]

So at the final solution should be所以在最终的解决方案应该是

[
  {'id': 2404, 'interfaces': [{'port': 78, 'module': 1 },{'port': 79, 'module': 1 } ]}
  {'id': 1234, 'interfaces': [{'port': 79, 'module': 1 }]} 
]

I defined your original nested list as the unmerged variable.我将您的原始嵌套列表定义为未unmerged变量。
The merged variable will contain the output merged变量将包含输出

unmerged = 
[
  {'id': 2404, 'interfaces': [{'port': 78, 'module': 1 }]},
  {'id': 2404, 'interfaces': [{'port': 79, 'module': 1 }]},
  {'id': 1234, 'interfaces': [{'port': 79, 'module': 1 }]},
]
merged = []

for unmerged_item in unmerged:
    match = next((item for item in merged if item['id'] == unmerged_item['id']), None)
    
    if match:
        match['interfaces'].extend(unmerged_item['interfaces'])
    else:
        merged.append(unmerged_item)

The output of the code will be as follows ( merged ):代码的输出将如下( merged ):

[
    {'id': 2404, 'interfaces': [{'port': 78, 'module': 1}, {'port': 79, 'module': 1}]}, 
    {'id': 1234, 'interfaces': [{'port': 79, 'module': 1}]}
]

Use a dictionary to accumulate the interfaces with the same id:使用字典来累积具有相同 id 的接口:

data = [
  {'id': 2404, 'interfaces': [{'port': 78, 'module': 1 }]},
  {'id': 2404, 'interfaces': [{'port': 79, 'module': 1 }]},
  {'id': 1234, 'interfaces': [{'port': 79, 'module': 1 }]}
]

lookup = {}
for d in data:
    iid = d["id"]
    if iid not in lookup:
        lookup[iid] = []
    lookup[iid].extend(d["interfaces"])

res = [{ "id" : iid, "interfaces" : interfaces } for iid, interfaces in lookup.items()]
print(res)

Output输出

[{'id': 2404, 'interfaces': [{'port': 78, 'module': 1}, {'port': 79, 'module': 1}]}, {'id': 1234, 'interfaces': [{'port': 79, 'module': 1}]}]

Alternative solution using collections.defaultdict :使用collections.defaultdict替代解决方案:

from collections import defaultdict
lookup = defaultdict(list)
for d in data:
    iid = d["id"]
    lookup[iid].extend(d["interfaces"])

res = [{ "id" : iid, "interfaces" : interfaces } for iid, interfaces in lookup.items()]

Special Case (the groups are contiguous)特殊情况(组是连续的)

If, and only if, the dictionaries id are contiguous, you could use itertools.groupby , as below:如果且仅当字典 id 是连续的,您可以使用itertools.groupby ,如下所示:

from itertools import groupby, chain
from operator import itemgetter

res = []
for iid, vs in groupby(data, key=itemgetter("id")):
    interfaces = chain.from_iterable(v["interfaces"] for v in vs)
    res.append({"id": iid, "interfaces" : list(interfaces) })

print(res)

Output输出

[{'id': 2404, 'interfaces': [{'port': 78, 'module': 1}, {'port': 79, 'module': 1}]}, {'id': 1234, 'interfaces': [{'port': 79, 'module': 1}]}]

If the groups are not contiguous you could sort your data, but that will make the approach less efficient (O(nlogn) due to the sorting) that the dictionary alternatives O(n).如果组不连续,您可以对数据进行排序,但这会使该方法的效率低于字典替代 O(n) 的效率(由于排序而为 O(nlogn))。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM