Eze*_*r K 6 python performance dictionary key-value
我有一本字典:
d = {'a':1, 'b':2, 'c':3, 'd':4}
Run Code Online (Sandbox Code Playgroud)
然后我有一个键列表:
l = ['a', 'b', 'z']
Run Code Online (Sandbox Code Playgroud)
我想要的结果是:
[1, 2, None]
Run Code Online (Sandbox Code Playgroud)
到目前为止我所做的是:
[d.get(k) for k in l]
Run Code Online (Sandbox Code Playgroud)
有更快的方法吗?也许没有for?
MSe*_*ert 13
你可以使用:
>>> list(map(d.get, l))
[1, 2, None]
Run Code Online (Sandbox Code Playgroud)
它有两个优点:
d.get一次查找 - 而不是每次迭代dict.get用C实现并且用C map实现它可以避免函数调用中的Python层(粗略地说细节有点复杂).至于时间(在Jupyter笔记本中的Python 3.6上执行):
d = {'a':1, 'b':2, 'c':3, 'd':4}
l = ['a', 'b', 'z']
%timeit list(map(d.get, l))
594 ns ± 41.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit [d.get(k) for k in l]
508 ns ± 17.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Run Code Online (Sandbox Code Playgroud)
请注意,在这种情况下,这实际上更慢!那是因为对于短迭代而言map,list开销占主导地位.因此,如果您希望在短迭代中更快地坚持您的方法.
随着时间的推移l你会看到list(map(...))最终变得更快:
d = {'a':1, 'b':2, 'c':3, 'd':4}
l = [random.choice(string.ascii_lowercase) for _ in range(10000)]
%timeit list(map(d.get, l))
663 µs ± 64.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit [d.get(k) for k in l]
1.13 ms ± 7.55 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Run Code Online (Sandbox Code Playgroud)
然而,这仍然"只是"快2倍.
重要的是要注意这里的瓶颈不是字典的大小,而是键列表的大小(当然还有方法查找时间,散列被查找的键所需的时间等)
考虑以下:
from timeit import Timer
d = {1: 'a'}
keys = [1 for _ in range(1000)]
def _map():
return list(map(d.get, keys))
def _map_single_lookup():
g = d.get
return list(map(g, keys))
def _list_comp():
return [d.get(key) for key in keys]
def _list_comp_single_lookup():
g = d.get
return [g(key) for key in keys]
print(min(Timer(_map).repeat(100, 100)))
print(min(Timer(_map_single_lookup).repeat(100, 100)))
print(min(Timer(_list_comp).repeat(100, 100)))
print(min(Timer(_list_comp_single_lookup).repeat(100, 100)))
# 0.009307396466818774
# 0.009261678214412816
# 0.018456645101335933
# 0.011634828724497837
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1348 次 |
| 最近记录: |