根据一个属性在Python中合并两个嵌套列表

4 投票
5 回答
1021 浏览
提问于 2025-04-18 10:39

我该如何在Python中根据一个属性合并两个嵌套列表呢?

比如说:

list1 = [[1,False,True],[2,True,True],[3,True,False]]
list2 = [[1,'Mr.','child'],[2,'Ms.','child'],[3,'Mr.','adult']]

我想运行类似这样的代码:

merged_list = merge(list1,list2, where list1[0]==list2[0])

所以最终的结果应该是:

merged_list = [[1,False,True,'Mr.','child'],[2,True,True,'Ms.','child'],[3,True,False,'Mr.','adult']]

我不想使用嵌套的for循环,因为这样不太好扩展;如果我试图合并两个有1,000,000行的数据列表,那就需要进行1,000,000,000,000次循环。

5 个回答

-1

你可以使用一个叫做 defaultdict 的工具,把所有第一个元素相同的列表合并在一起,然后再把它转换成你想要的输出格式。

from collections import defaultdict

list1 = [[1,False,True],[2,True,True],[3,True,False]]
list2 = [[1,'Mr.','child'],[2,'Ms.','child'],[3,'Mr.','adult']]

d = defaultdict(list)
for item in list1 + list2:
    d[item[0]] += item[1:]

merged_list = [[k]+v for k, v in d.items()]

print merged_list

# OUTPUT:  [[1, False, True, 'Mr.', 'child'], [2, True, True, 'Ms.', 'child'], [3, True, False, 'Mr.', 'adult']]
-1

你可以用enumerate来比较两个列表中的元素。

list1 = [[1,False,True],[2,True,True],[3,True,False]]
list2 = [[1,'Mr.','child'],[2,'Ms.','child'],[3,'Mr.','adult']]

merged=[]
for i,j in enumerate(list1):
    if list2[i][0]==j[0]:
        merged.append(j+ list2[i][1:])
print merged
[[1, False, True, 'Mr.', 'child'], [2, True, True, 'Ms.', 'child'], [3, True, False, 'Mr.', 'adult']]

你也可以使用zip。

merged=[]
for  i, j in zip( list1,list2):
    if i[0] == j[0]:
        merged.append(i+j[1:])

使用这两种循环的性能似乎差不多。

In [3]: %%timeit
   ...: merged=[]
   ...: for i,j in enumerate(list1):
   ...:     if list2[i][0]==j[0]:
   ...:         merged.append(j+ list2[i][1:])
   ...: 
1000000 loops, best of 3: 1.79 µs per loop

In [4]: %%timeit
   ...: merged=[]
   ...: for  i, j in zip( list1,list2):
   ...:     if i[0] == j[0]:
   ...:         merged.append(i+j[1:])
   ...: 
1000000 loops, best of 3: 1.76 µs per loop
-1
list1 = [[1,False,True],[2,True,True],[3,True,False]]
list2 = [[1,'Mr.','child'],[2,'Ms.','child'],[3,'Mr.','adult']]
## if the order of the items doesn't matter , and you don't 
## need elements to be repeated you can do:
# res = [list(set(a+list2[i])) for i, a in enumerate(list1) if a[0] == list2[i][0]]
## otherwise you can do:
res = [list(a+list2[i][1:]) for i, a in enumerate(list1) if a[0] == list2[i][0]]
print res

输出:

[[1, False, True, 'Mr.', 'child'], [2, True, True, 'Ms.', 'child'], [3, True, False, 'Mr.', 'adult']]
0

下面的代码怎么样:

>>> list1 = [[1,False,True],[2,True,True],[3,True,False]]
>>> list2 = [[1,'Mr.','child'],[2,'Ms.','child'],[3,'Mr.','adult']]
>>> merge = [list([x[0]] + x[1:] + y[1:]) for x in list1 for y in list2 if x[0] == y[0]]
>>> merge
[[1, False, True, 'Mr.', 'child'], [2, True, True, 'Ms.', 'child'], [3, True, False, 'Mr.', 'adult']]
>>> 
2

你有没有想过通过字典来合并它们呢?

def list_merge(list1, list2):
    d = {}
    for x in list1 + list2:
        d.setdefault(x[0], []).extend(x[1:])
    return [[x] + y for x, y in d.items()]

撰写回答