2013-05-06 54 views
1

我想從幾個鍵的列表中獲取一維值列表。列表理解來自列表中的字典的拼版值

這就是我如何做到這一點的紅寶石:

irb> list_ = [{a:1, b:2, c:3}, {a:4, b:5, c:6}] 

irb> list_.flat_map{ |dict_| dict_.values_at :b, :c } 
=> [2, 3, 5, 6] 

現在我該怎麼辦呢在Python?

+0

@Charles,讓我問:什麼是錯的標籤?爲什麼我會看到「4位訂戶」,但沒有問題存在。 – Nakilon 2013-05-06 17:06:09

+0

'one-liner'是一個[meta標籤](http://blog.stackoverflow.com/2010/08/the-death-of-meta-tags/)。標記訂閱在標記刪除後不存在。你不會相信訂閱我永恆的剋星標籤「服務器」的人數。 – Charles 2013-05-06 18:16:49

回答

4

我會做這樣的事情:

>>> lst = [{'a': 1, 'b': 2, 'c': 3}, {'a': 4, 'b': 5, 'c': 6}] 
>>> [dct[i] for dct in lst for i in ('b', 'c')] 
[2, 3, 5, 6] 
+1

+1這是優雅的,幾乎是我的解決方案的兩倍。 – 2013-05-06 10:16:30

2

您可以使用itertools.chain

>>> from itertools import chain,imap 

>>> lis = [{'a':1, 'b':2, 'c':3}, {'a':4, 'b':5, 'c':6}] 

>>> list(chain.from_iterable((x[y] for y in ('b','c')) for x in lis)) 
[2, 3, 5, 6] 

或列表理解版本(更少的內存效率):

>>> list(chain.from_iterable([x[y] for y in ('b','c')] for x in lis)) 
[2, 3, 5, 6] 

正如jamylak建議你也可以使用operator.itemgetteritertools.imapitertools.chain,這甚至快於Volatility使用的LC version

>>> from operator import itemgetter 
>>> list(chain.from_iterable(imap(itemgetter('b', 'c'), lis))) 
[2, 3, 5, 6] 

時間:

>>> lis = [{'a':1, 'b':2, 'c':3}, {'a':4, 'b':5, 'c':6}]*10**5 

>>> %timeit list(chain.from_iterable((x[y] for y in ('b','c')) for x in lis)) 
1 loops, best of 3: 276 ms per loop 

>>> %timeit list(chain.from_iterable([x[y] for y in ('b','c')] for x in lis)) 
1 loops, best of 3: 183 ms per loop 

>>> %timeit list(chain.from_iterable(imap(itemgetter('b', 'c'), lis))) #winner 
10 loops, best of 3: 74.6 ms per loop 

>>> %timeit [dct[i] for dct in lis for i in ('b', 'c')] 
10 loops, best of 3: 98.4 ms per loop 
+0

您可以從發生器中刪除不必要的括號,它們不起任何作用。也嘗試計時'list(chain.from_iterable(imap(itemgetter('b','c'),lst)))'它非常接近列表comp(實際上在我的系統上用'1ms'擊敗它 – jamylak 2013-05-06 10:40:55

+0

@ jamylak它比LC版更快 – 2013-05-06 10:44:53

+0

我應該也提到過,我從'map'到'imap'做了一個快速編輯,試一下也是這樣:) – jamylak 2013-05-06 10:49:20