2010-07-22 121 views
61

我想從元組列表中獲取第n個元素。如何從python中的元組列表中提取第n個元素?

我有類似:

elements = [(1,1,1),(2,3,7),(3,5,10)] 

我只希望每個元組的第二個元素提取到一個列表:

seconds = [1, 3, 5] 

我知道,它可以與for循環進行,但我想知道是否有另一種方式,因爲我有成千上萬的元組。

回答

123
[x[1] for x in elements] 
23

我知道,它可以用FOR做,但我想知道是否有另一種方式

還有另一種方式。您還可以mapitemgetter做到這一點:

>>> from operator import itemgetter 
>>> map(itemgetter(1), elements) 

這仍然執行循環內部,雖然它比列表理解稍微慢一點:

setup = 'elements = [(1,1,1) for _ in range(100000)];from operator import itemgetter' 
method1 = '[x[1] for x in elements]' 
method2 = 'map(itemgetter(1), elements)' 

import timeit 
t = timeit.Timer(method1, setup) 
print('Method 1: ' + str(t.timeit(100))) 
t = timeit.Timer(method2, setup) 
print('Method 2: ' + str(t.timeit(100))) 

結果:

 
Method 1: 1.25699996948 
Method 2: 1.46600008011 

如果你需要迭代一個列表,那麼使用for就可以了。

+0

一個小的補充:在python-3.x中,基準測試會顯示map只需要幾分之一毫秒。這是因爲它會返回一個迭代器。 method2 ='list(map(itemgetter(1),elements))'呈現舊行爲。 – 2011-05-13 11:59:31

+0

這應該是公認的答案。 – 2016-09-06 17:14:10

21

這也適用於:

zip(*elements)[1] 

(我主要是發佈此,爲了證明自己,我已經groked zip ...)

看到它在行動:

>>> help(zip) 

關於模塊內置函數zip的幫助內建

拉鍊(...)

拉鍊(SEQ1 [,SEQ2 [...]]) - > [(SEQ1 [0],SEQ2 [0] ...),(...) ]

返回元組列表,其中每個元組包含來自每個參數序列的第i個元素 。返回的列表被截短長度爲 ,長度爲最短參數序列的長度。

>>> elements = [(1,1,1),(2,3,7),(3,5,10)] 
>>> zip(*elements) 
[(1, 2, 3), (1, 3, 5), (1, 7, 10)] 
>>> zip(*elements)[1] 
(1, 3, 5) 
>>> 

整潔的事情我今天瞭解到:使用*list在參數來創建一個函數的參數列表...

+2

並使用'** dict'創建關鍵字參數:'def test(foo = 3,bar = 3):return foo * bar' then'd = {'bar':9,'foo'= 12};打印測試(** d)' – 2010-07-22 12:58:58

+0

@Wayne Werner:是的。這些東西都只是被動的知識(我不經常使用它) - 但它是時刻提醒,所以你知道在哪裏/什麼尋找...... – 2010-07-22 13:14:53

+0

真實的故事 - 我發現,在我經常使用的任何東西足夠的(Python,vim),我傾向於需要提醒我已經忘記的整齊/酷的功能,因爲我不經常使用它們*。 – 2010-07-22 14:26:10

9

發現這是我在尋找它的方式是最快的拉第二個元素的2元組列表。不是我想要的,但跑了相同的測試,如圖與3方法以及測試方法拉鍊

setup = 'elements = [(1,1) for _ in range(100000)];from operator import itemgetter' 
method1 = '[x[1] for x in elements]' 
method2 = 'map(itemgetter(1), elements)' 
method3 = 'dict(elements).values()' 
method4 = 'zip(*elements)[1]' 

import timeit 
t = timeit.Timer(method1, setup) 
print('Method 1: ' + str(t.timeit(100))) 
t = timeit.Timer(method2, setup) 
print('Method 2: ' + str(t.timeit(100))) 
t = timeit.Timer(method3, setup) 
print('Method 3: ' + str(t.timeit(100))) 
t = timeit.Timer(method4, setup) 
print('Method 4: ' + str(t.timeit(100))) 

Method 1: 0.618785858154 
Method 2: 0.711684942245 
Method 3: 0.298138141632 
Method 4: 1.32586884499 

所以在快兩倍,如果你有一個元組2對,只是轉換到一個字典,並採取值。

+0

這可能是顯而易見的,但我會提及'dict(elements).values() '將產生一元字典而不是列表comprahension或map。這正是我想要的(我對獨特的關注點感興趣)(+1和非常感謝張貼),但其他人可能會問爲什麼字典更快 - 它不會分配內存,而只是檢查現有元素。 – Greg0ry 2016-12-21 13:34:07

2
map (lambda x:(x[1]),elements) 
+4

考慮添加一些解釋。 – fedorqui 2014-10-08 13:44:09

0

計時爲的Python 3.6用於從2元組列表中提取第二元件。

此外,還添加了numpy數組方法,它更易於閱讀(但可以說比列表理解更簡單)。

from operator import itemgetter 
elements = [(1,1) for _ in range(100000)] 

%timeit second = [x[1] for x in elements] 
%timeit second = list(map(itemgetter(1), elements)) 
%timeit second = dict(elements).values() 
%timeit second = list(zip(*elements))[1] 
%timeit second = np.array(elements)[:,1] 

和時序:

list comprehension: 4.73 ms ± 206 µs per loop 
list(map):   5.3 ms ± 167 µs per loop 
dict:    2.25 ms ± 103 µs per loop 
list(zip)   5.2 ms ± 252 µs per loop 
numpy array:  28.7 ms ± 1.88 ms per loop 

注意map()zip()再也不會返回一個列表,因此顯式轉換。

相關問題