[英]Python dictionary: Get list of values for list of keys
是否有內置/快速的方法來使用字典的鍵列表來獲取相應項目的列表?
例如我有:
>>> 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 之外,還有其他幾種方式:
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(...))
作為列表。
一點速度比較:
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)
。
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 的結果幾乎相同。
這里有三種方法。
找不到密鑰時KeyError
:
result = [mapping[k] for k in iterable]
缺失鍵的默認值。
result = [mapping.get(k, default_value) for k in iterable]
跳過丟失的鍵。
result = [mapping[k] for k in iterable if k in mapping]
嘗試這個:
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]
嘗試這個:
mydict = {'one': 1, 'two': 2, 'three': 3}
mykeys = ['three', 'one'] # if there are many keys, use a set
[mydict[k] for k in mykeys]
=> [3, 1]
new_dict = {x: v for x, v in mydict.items() if x in mykeys}
或者只是mydict.keys()
這是對字典的內置方法調用。 還可以探索mydict.values()
和mydict.items()
。
//啊,OP帖子讓我很困惑。
Pandas 非常優雅地做到了這一點,盡管 ofc 列表推導式在技術上總是更加 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}
如果您發現自己經常這樣做,您可能希望將dict
子類化以獲取鍵列表並返回值列表。
>>> d = MyDict(mydict)
>>> d[mykeys]
[3, 1]
這是一個演示實現。
class MyDict(dict):
def __getitem__(self, key):
getitem = super().__getitem__
if isinstance(key, list):
return [getitem(x) for x in key]
else:
return getitem(key)
很好地子類化dict
需要更多的工作,而且您可能想要實現.get()
、 .__setitem__()
和.__delitem__()
等。
reduce(lambda x,y: mydict.get(y) and x.append(mydict[y]) or x, mykeys,[])
以防字典中沒有鍵。
Python關閉后:從具有給定順序的 dict 值創建列表的有效方法
在不構建列表的情況下檢索密鑰:
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
與列表給出的順序匹配
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.