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,[])
有没有在字典中的键。