为了账号安全,请及时绑定邮箱和手机立即绑定

Python字典:获取键列表的值列表

Python字典:获取键列表的值列表

呼唤远方 2019-08-30 18:02:48
是否有内置/快速方法使用字典键列表来获取相应项的列表?比如我有:>>> mydict = {'one': 1, 'two': 2, 'three': 3}>>> mykeys = ['three', 'one']如何使用mykeys字典中的相应值作为列表?>>> mydict.WHAT_GOES_HERE(mykeys)[3, 1]
查看完整描述

3 回答

?
侃侃无极

TA贡献2051条经验 获得超10个赞

除list-comp之外的其他几种方式:


如果找不到密钥,则构建列表并抛出异常: map(mydict.__getitem__, mykeys)

None如果未找到密钥,则构建列表:map(mydict.get, mykeys)

或者,使用operator.itemgetter可以返回一个元组:


from operator import itemgetter

myvalues = itemgetter(*mykeys)(mydict)

# use `list(...)` if list is required

注意:在Python3中,map返回迭代器而不是列表。使用list(map(...))了列表。


查看完整回答
反对 回复 2019-08-30
?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

一点速度比较:


Python 2.7.11 |Anaconda 2.4.1 (64-bit)| (default, Dec  7 2015, 14:10:42) [MSC v.1500 64 bit (AMD64)] on win32

In[1]: l = [0,1,2,3,2,3,1,2,0]

In[2]: m = {0:10, 1:11, 2:12, 3:13}

In[3]: %timeit [m[_] for _ in l]  # list comprehension

1000000 loops, best of 3: 762 ns per loop

In[4]: %timeit map(lambda _: m[_], l)  # using 'map'

1000000 loops, best of 3: 1.66 µs per loop

In[5]: %timeit list(m[_] for _ in l)  # a generator expression passed to a list constructor.

1000000 loops, best of 3: 1.65 µs per loop

In[6]: %timeit map(m.__getitem__, l)

The slowest run took 4.01 times longer than the fastest. This could mean that an intermediate result is being cached 

1000000 loops, best of 3: 853 ns per loop

In[7]: %timeit map(m.get, l)

1000000 loops, best of 3: 908 ns per loop

In[33]: from operator import itemgetter

In[34]: %timeit list(itemgetter(*l)(m))

The slowest run took 9.26 times longer than the fastest. This could mean that an intermediate result is being cached 

1000000 loops, best of 3: 739 ns per loop

所以列表理解和itemgetter是最快的方法。


更新:对于大型随机列表和地图,我有一些不同的结果:


Python 2.7.11 |Anaconda 2.4.1 (64-bit)| (default, Dec  7 2015, 14:10:42) [MSC v.1500 64 bit (AMD64)] on win32

In[2]: import numpy.random as nprnd

l = nprnd.randint(1000, size=10000)

m = dict([(_, nprnd.rand()) for _ in range(1000)])

from operator import itemgetter

import operator

f = operator.itemgetter(*l)

%timeit f(m)

%timeit list(itemgetter(*l)(m))

%timeit [m[_] for _ in l]  # list comprehension

%timeit map(m.__getitem__, l)

%timeit list(m[_] for _ in l)  # a generator expression passed to a list constructor.

%timeit map(m.get, l)

%timeit map(lambda _: m[_], l)

1000 loops, best of 3: 1.14 ms per loop

1000 loops, best of 3: 1.68 ms per loop

100 loops, best of 3: 2 ms per loop

100 loops, best of 3: 2.05 ms per loop

100 loops, best of 3: 2.19 ms per loop

100 loops, best of 3: 2.53 ms per loop

100 loops, best of 3: 2.9 ms per loop

因此,在这种情况下,明确的赢家是f = operator.itemgetter(*l); f(m)明确的局外人:map(lambda _: m[_], l)。


Python 3.6.4的更新:


import numpy.random as nprnd

l = nprnd.randint(1000, size=10000)

m = dict([(_, nprnd.rand()) for _ in range(1000)])

from operator import itemgetter

import operator

f = operator.itemgetter(*l)

%timeit f(m)

%timeit list(itemgetter(*l)(m))

%timeit [m[_] for _ in l]  # list comprehension

%timeit list(map(m.__getitem__, l))

%timeit list(m[_] for _ in l)  # a generator expression passed to a list constructor.

%timeit list(map(m.get, l))

%timeit list(map(lambda _: m[_], l)

1.66 ms ± 74.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

2.1 ms ± 93.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

2.58 ms ± 88.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

2.36 ms ± 60.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

2.98 ms ± 142 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

2.7 ms ± 284 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

3.14 ms ± 62.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

因此,Python 3.6.4的结果几乎相同。


查看完整回答
反对 回复 2019-08-30
  • 3 回答
  • 0 关注
  • 2079 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信