2016-01-21 92 views
2

考慮的元組的兩個列表:將基於一個共同的元組元素的元組的列表

data1 = [([X1], 'a'), ([X2], 'b'), ([X3], 'c')] 
data2 = [([Y1], 'a'), ([Y2], 'b'), ([Y3], 'c')] 

len(data1) == len(data2)

每個元組包含兩個元素:

  1. 一些字符串列表(即[X1]
  2. A common element for data1data2:字符串'a','b'等等。

我想將它們合併爲以下幾點:

[('a', [X1], [Y1]), ('b', [X2], [Y2]),...] 

有誰知道我能做到這一點?

+0

@Idio,是的,我沒有,但還是願意看其他民間的想法的,有什麼證明是非常有益的。 – Mrv

回答

7

可以使用zip函數和一個列表理解:

[(s1,l1,l2) for (l1,s1),(l2,s2) in zip(data1,data2)] 
5

@Kasramvd的解決方案是好如果訂單是在data名單所有元素中的相同。如果不是這樣,它不會考慮到這一點。

一個解決方案,確實,利用defaultdict

from collections import defaultdict 

d = defaultdict(list) # values are initialized to empty list 

data1 = [("s1", 'a'), ("s2", 'c'), ("s3", 'b')] 
data2 = [("s1", 'c'), ("s2", 'b'), ("s3", 'a')] 

for value, common in data1 + data2: 
    d[common].append(value) 

爲了得到它的列表,只需在list()調用它包:

res = list(d.items()) 
print(res) 
# Prints: [('b', ['s3', 's2']), ('a', ['s1', 's3']), ('c', ['s2', 's1'])] 
1

我們可以在單個理解表達式中使用減少函數來執行此操作

from functools import reduce 
from operator import add 
[tuple([x]+reduce(add,([y[0]] for y in data1+data2 if y[1]==x))) for x in set(y[1] for y in data1+data2)] 

如果名單是大,使data1+data2施加了嚴格的時間或內存罰款,這可能是更好的預先計算它

combdata = data1+data2 
[tuple([x]+reduce(add,[y[0]] for y in combdata if y[1]==x))) for x in set(y[1] for y in combdata)] 

該解決方案不依賴於所有「鑰匙」在這兩個發生列表或訂單是相同的。

如果返回順序很重要,我們甚至可以做

sorted([tuple([x]+reduce(add,([y[0]] for y in data1+data2 if y[1]==x))) for x in set(y[1] for y in data1+data2)],key = lambda x,y=[x[0] for x in data1+data2]: y.index(x[1])) 

,以確保順序是一樣的,在最初的名單。此外,預計算data1+data2

sorted([tuple([x]+reduce(add,([y[0]] for y in combdata if y[1]==x))) for x in set(y[1] for y in combdata)],key = lambda x,y=[x[0] for x in combdata]: y.index(x[1])) 
相關問題