2011-09-19 106 views
1

我列出的两份名单 - 即合并两个外部列表基于迭代内部列表值

[['1', 'expired', 'test', '0'], ['31', 'active', 'test', '1']] 

以及

[['1', 'Andrew', 'Alexander'], ['31', 'John', 'Smith']] 

让我们称之为list1list2

我想合并list1list2,但只有当(注意,这是伪代码,试图找出如何在Python中编程)

x[0] in list1 == x[0] in list2 

我不确定如何写出来。

通过合并我的意思是(伪代码)

list[x] = list1[x] + list2[x] while x[0] in list1 == x[0] in list2 

输出期望:

[['1', 'expired', 'test', '0', '1', 'Andrew', 'Alexander'], ['31', 'active', 'test', '1', '31', 'John', 'Smith']] 

的唯一关键点是,并不是所有的x的[0]的要匹配完美。

+0

你说的'合并'是什么意思?什么是期望的输出? – infrared

+1

请给出你想要的例子的输出 - 它仍然不是很清楚。 – agf

+0

仍试图找出哪些是适合我的正确答案。我很多未被选中的答案都是这样的。我也一直试图给过去的问题提供检查标记。我正在努力成为社区的一员! –

回答

1

使用agf的想法采用collections.defaultdict,这在O(m + n)中,其中mn是列表的长度。

import collections 
import itertools 

x=[['1', 'expired', 'test', '0'], ['31', 'active', 'test', '1']] 
y=[['1', 'Andrew', 'Alexander'], ['31', 'John', 'Smith']] 

result=collections.defaultdict(list) 
for item in itertools.chain(x,y): 
    result[item[0]].append(item) 
result=[list(itertools.chain.from_iterable(value)) for value in result.values()] 
print(result) 

产生

[['1', 'expired', 'test', '0', '1', 'Andrew', 'Alexander'], ['31', 'active', 'test', '1', '31', 'John', 'Smith']] 

在注释的OP表示期望的输出是

[['1', 'expired', 'test', '0', 'Andrew', 'Alexander'], ['31', 'active', 'test', '1', 'John', 'Smith']] 

(这比张贴在原来的问题所需的输出不同。)

Then:

import collections 
import itertools 

x=[['1', 'expired', 'test', '0'], ['31', 'active', 'test', '1']] 
y=[['1', 'Andrew', 'Alexander'], ['31', 'John', 'Smith']] 

result={} 
for item in itertools.chain(x,y): 
    result.setdefault(item[0],item[:1]).extend(item[1:]) 
result=result.values() 
print(result) 

这是几次我已经使用setdefaultcollections.defaultdict更方便发现之一。

1

如果你想[[1, 'a'], [2, 'b']][[1, 'c'], [3, 'd']]合并[[1, 'a', 'c'], [2, 'b'], [3, 'd']]

from collections import defaultdict 
dict1_2 = defaultdict(list) 
dict1_2.update((item[0], item[1:]) for item in list1) 
for item in list2: 
    dict1_2[item[0]].append(item[1:]) 

如果你想让他们合并[[1, 'a', 'c']]

dict1 = dict((item[0], item[1:]) for item in list1) 
dict1_2 = {} 
for item in list2: 
    key = item[0] 
    if key in dict1: 
     dict1_2[key] = dict1[key] + item[1:] 

您使用的是item[0]钥匙,所以你应该使用适合的数据类型。在这种情况下,这是一个字典/映射。

这工作(平均)以线性时间,O(M + n)(其中m和n是列表的长度)。使用嵌套循环或任何解决方案类似的将是O(m * n个)

如果你真的需要把数据传回的列表,你可以做

list1_2 = [[key] + value for key, value in dict1_2.iteritems()] 
+0

他们并不完全相同。其他列表中有些是不同的/不存在的。这就是为什么我在Python中这样做的原因,而不是说,只是在Excel中合并两个列表。 –

+0

这就是说,我想[['1','过期','测试','0','安德鲁','亚历山大'], ['31','主动','测试','1 ','John','Smith']] –

+0

@Andrew重新编辑。根据你想要在一个列表或其他列表中完成的项目,我提供了两个版本。 – agf

0
resultlist = [] 
for x in list1: 
    for y in list2: 
     if x[0] == y[0]: 
      resultlist.append(x+y) 
+0

OP所说的项目应该只在第一个元素在两个列表中相同时添加 - 或者我错了吗? – infrared

+0

这是O(len(list1)* len(list2))时间,它可以在线性平均时间内完成。 – agf

0

不是最好的方式,但绝对简明而难以阅读,如果这就是你所追求的:

>>> l1 = [['1', 'expired', 'test', '0'], ['31', 'active', 'test', '1']] 
>>> l2 = [['1', 'Andrew', 'Alexander'], ['31', 'John', 'Smith']] 

>>> [sl1 + list(*[sl2[1:] for sl2 in l2 if sl2[0]==sl1[0]]) for sl1 in l1] 

[['1', 'expired', 'test', '0', 'Andrew', 'Alexander'], ['31', 'active', 'test', '1', 'John', 'Smith']] 

请不要在任何真正的代码中实际使用它。

+0

如果你想'next'(如果sl2 [0] == sl1 [0]),[]]'而不是你想出的那个疯狂列表,那么你需要'next((sl2 [1:] for sl2 in l2 if sl2 [0] == sl1 [0]),[])':)。此外,这将添加只存在于“list1”中的项目,但不包含仅存在于“list2”中的项目 - 我不知道他是否希望它们添加或不添加,但我确定他不希望它不对称。 – agf

0
l1 = [['1', 'expired', 'test', '0'], ['31', 'active', 'test', '1']] 
l2 = [['1', 'Andrew', 'Alexander'], ['31', 'John', 'Smith'], ['51', 'Johnny', 'Nomatch']] 

from itertools import groupby, chain 
from operator import itemgetter 

all = sorted(chain(l1,l2), key=itemgetter(0)) # puts the related lists together 
groups = groupby(all, itemgetter(0)) # groups them by first element 
chains = (group for key, group in groups) # get each group 
print [list(chain.from_iterable(g)) for g in chains] # merge them 

这是一个oneliner ;-)

项不匹配的也包括在内。您可以通过简单地检查len(group) > 4来过滤它们。