1

我想从字典列表的几个键中获取一维值列表。

这就是我在 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 中做到这一点?

4

2 回答 2

3

我会做这样的事情:

>>> 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]
于 2013-05-06T10:10:07.627 回答
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.itemgetterand itertools.imapwith 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
于 2013-05-06T10:10:01.297 回答