合并/追加共享公共项目的列表

时间:2011-10-14 17:02:18

标签: python

标题可能会产生误导,因此在出现真正问题的术语时,请随意更改措辞。 =)

在这种情况下,我知道列表可能与元组互换,大多数情况下。就我而言,最终结果可以是任何可迭代的。

我有两个列表清单。假设它们是:

list_a = [[1, 'f00d'], [2, 'dead'], [3, 'beef']]
list_b = [[1, 'frankenbeans'], [2, 'chickensoup'], [3, 'spaceballs']]

两个列表必然长度相同,也不保证它们包含共同的第一个元素。

我要做的是创建一个新的list-of-lists / list-of-tuples / list-of-dicts / what,如下:

list_c = [[1, 'f00d', 'frankenbeans'], [2, 'dead', 'chickensoup'], [3, 'beef', 'spaceballs']

更新: 基本上,我知道这些列表中常见“ID”的位置,虽然它不一定是顺序的,但列表列表也不是相同的顺序(但是是一个整数)。我正在寻找一种基于该公共ID创建一组新子列表的有效方法。

天真的方式:

new_list = []
for list_a_list in list_a:
  for list_b_list in list_b:
    if list_a_list[0] = list_b_list[0]:
      new_list.append([list_a_list[0], list_a_list[1], list_b_list[1]])

......或者其他一些。给我的感觉是有一种更“聪明”的方式来做到这一点,但我有点不好意思。

更新
如果我提到列表列表每次都有数千到一百万件物品,它会增加任何影响吗?

3 个答案:

答案 0 :(得分:0)

from collections import defaultdict
from itertools import chain

final = defaultdict(list)

for idx, value in chain(l1, l2):
  final[idx].append(value)

# and if you have to have a list of lists at the end
finalList = [[k] + v for k, v in final.iteritems()]

答案 1 :(得分:0)

您的输入列表首先应该是字典:

dict_a = dict(list_a)
dict_b = dict(list_b)
dict_c = dict((k, [v, dict_b[k]]) for k,v in dict_a.items())

如果不保证在两个列表中都出现密钥,则必须更加小心:

all_keys = set(dict_a.keys()) | set(dict_b.keys())
dict_c = dict((k, (dict_a.get(k), dict_b.get(k))) for k in all_keys)

例如,对于list_a = [(1, 'a')]list_b = [(1, 'b'), (2, 'c')],上述内容会将dict_c设置为{1: ('a', 'b'), 2: (None, 'c')}

答案 2 :(得分:0)

itertools.groupby()对此类任务很有帮助:

from itertools import groupby, chain
from operator import itemgetter

list_a = [[1, 'f00d'], [2, 'dead'], [3, 'beef']]
list_b = [[1, 'frankenbeans'], [2, 'chickensoup'], [3, 'spaceballs']]

combined = [(k, [v[1] for v in g]) for k, g in
            groupby(sorted(list_a+list_b), key=itemgetter(0))]

print combined

请注意,在我们可以使用groupby之前,有必要创建一个组合list_a和list_b的新排序列表,因为groupby假定列表已经按键排序。