2011-09-19 103 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來過濾它們。