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

有一个内置/快捷的方式来使用一个字典列表来获取相应项目的列表?

比如我有:

>>> mydict = {'one': 1, 'two': 2, 'three': 3} >>> mykeys = ['three', 'one'] 

我如何使用mykeys来获取字典中的相应值作为列表?

 >>> mydict.WHAT_GOES_HERE(mykeys) [3, 1] 

列表理解似乎是一个很好的方法来做到这一点:

 >>> [mydict[x] for x in mykeys] [3, 1] 

除了list-comp之外,还有其他一些方法:

  • build立列表并抛出exception,如果没有find键: map(mydict.__getitem__, mykeys)
  • 如果没有find密钥,则使用None构build列表: map(mydict.get, mykeys)

另外,使用operator.itemgetter可以返回一个元组:

 from operator import itemgetter myvalues = itemgetter(*mykeys)(mydict) # use `list(...)` if list is required 

一点速度比较:

 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) f = operator.itemgetter(*l); f(m) ,并明确的局外人: map(lambda _: m[_], l)

尝试这个:

 mydict = {'one': 1, 'two': 2, 'three': 3} mykeys = ['three', 'one','ten'] newList=[mydict[k] for k in mykeys if k in mydict] print newList [3, 1] 

这里有三种方法。

未find密钥时KeyError

 result = [mapping[k] for k in iterable] 

缺less密钥的默认值。

 result = [mapping.get(k, default_value) for k in iterable] 

跳过丢失的键。

 found_keys = mapping.keys() & iterable result = [mapping[k] for k in iterable if k in found_keys] 

或者只是mydict.keys()这是一个内置的方法调用字典。 另外探索mydict.values()mydict.items()

//啊,OP发帖糊涂了我。

尝试这个:

 mydict = {'one': 1, 'two': 2, 'three': 3} mykeys = {'three', 'one'} # if there are many keys, use a set [v for k, v in mydict.items() if k in mykeys] => [3, 1] 

以上将在Python 3.x中正常工作。 在Python 2.x中,这是首选,因为它使用迭代器:

 [v for k, v in mydict.iteritems() if k in mykeys] 

pandas做这个非常优雅,虽然列表的理解总是更技术Pythonic。 我现在没有时间进行速度比较(稍后我会回来,并把它放进去):

 import pandas as pd mydict = {'one': 1, 'two': 2, 'three': 3} mykeys = ['three', 'one'] temp_df = pd.DataFrame().append(mydict) # You can export DataFrames to a number of formats, using a list here. temp_df[mykeys].values[0] # Returns: array([ 3., 1.]) # If you want a dict then use this instead: # temp_df[mykeys].to_dict(orient='records')[0] # Returns: {'one': 1.0, 'three': 3.0} 

closuresPython之后:有效的方式来创build一个给定顺序的字典值的列表

在没有构build列表的情况下检索密钥:

 from __future__ import (absolute_import, division, print_function, unicode_literals) import collections class DictListProxy(collections.Sequence): def __init__(self, klist, kdict, *args, **kwargs): super(DictListProxy, self).__init__(*args, **kwargs) self.klist = klist self.kdict = kdict def __len__(self): return len(self.klist) def __getitem__(self, key): return self.kdict[self.klist[key]] myDict = {'age': 'value1', 'size': 'value2', 'weigth': 'value3'} order_list = ['age', 'weigth', 'size'] dlp = DictListProxy(order_list, myDict) print(','.join(dlp)) print() print(dlp[1]) 

输出:

 value1,value3,value2 value3 

与列表中给出的顺序相匹配

 reduce(lambda x,y: mydict.get(y) and x.append(mydict[y]) or x, mykeys,[]) 

有没有在字典中的键。