2012-10-31 283 views
5

這是我期待做的。我有兩個元組列表。構建元素的列表,以便在列表1元組的第一個元素2比較兩個元組列表中元素之間的元素

list1 = [('a', 2), ('b', 3), ('z', 5)] 

list2 = [('a', 1), ('b', 2), ('c', 3)] 

list3 = ['a','b'] 

注意的第一個元素相匹配的元組列表:可以有沒有重複的第一要素

看着蟒蛇名單後理解,這就是我所做的

[x[0] for x in list1 if (x[0] in [y[0] for y in list2])] 

我的問題是這將是一個有經驗的Python程序員如何編碼?編碼完成後,我仍然覺得這很難閱讀。如果不是怎麼回事,你會做

+2

如若'[ 'A', 'B', 'C']'和'[ '一個', 'C']''匹配」 c''? –

+0

我會說是的最終名單將是['a','c'],但在我的例子中,我特別查看元組列表 – sidg11

+0

你能解釋一下,「一個元組」是什麼?我不明白你說的關於你想要完成的一個詞... – Gandaro

回答

8

我會使用zip()

In [25]: l1 = [('a', 2), ('b', 3), ('z', 5)] 

In [26]: l2 = [('a', 1), ('b', 2), ('c', 3)] 

In [27]: [x[0] for x,y in zip(l1,l2) if x[0]==y[0]] 
Out[27]: ['a', 'b'] 

編輯:

In [36]: [x[0] for x in l1 if any(x[0]==y[0] for y in l2)] 
Out[36]: ['a', 'b'] 
閱讀您的評論上面,它看起來像您正在尋找這樣的事情後,

或使用sets

In [43]: from operator import itemgetter 

In [44]: set(map(itemgetter(0),l1)) & set(map(itemgetter(0),l2)) 
Out[44]: set(['a', 'b']) 
+0

當然!打我30秒。注意:通過在列表理解之外的'zip'來提高性能,以便每次都不重新計算'zip' – inspectorG4dget

+0

@ inspectorG4dget我認爲'zip()'只被調用一次,看看字節代碼。 –

+1

你說得對。好決定!'dis' ftw :) – inspectorG4dget

3

我想你想使用set在這兒:

set(x[0] for x in list1).intersection(y[0] for y in list2) 

或使用語法糖:

{x[0] for x in list1} & {y[0] for y in list2} 

這兩者導致:

set(['a', 'b']) 
2

我認爲它可能是更清晰在這裏使用集(因爲你沒有重複的元素):

set1 = set(el[0] for el in list1) 
set2 = set(el[0] for el in list2) 
set3 = set1 & set2 # set intersection 
# list3 = list(set3) 
1

假設你想要的元組的第一要素的交集,您可以使用Python 2.7版推出的辭典鍵的觀點:

dict(list1).viewkeys() & dict(list2).viewkeys() 

這會比你的長列表的解決方案更有效,因爲它具有線性運行時(與您的解決方案的O(mn)相反),但以任意順序返回結果(與list1定義的順序相反)。

在Python 3.x中,這將是

dict(list1).keys() & dict(list2).keys()