我想从字典列表的几个键中获取一维值列表。
这就是我在 Ruby 中的做法:
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 中做到这一点?
我会做这样的事情:
>>> 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]
您可以使用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.itemgetter
and itertools.imap
with itertools.chain
,这甚至比Volatility使用的LC 版本更快。
>>> 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