当大于当前键值时,在python中设置字典值的最快方法

时间:2015-07-16 06:07:26

标签: python dictionary

我遇到的情况是,当且仅当新值大于旧值时,必须将字典键设置为值(总是整数)。分析揭示了我目前正在做的方式是占用某个功能的整整1/3的时间。以下是我目前正在做的事情:

some_dict[k] = max(new_val, some_dict.get(k, 0))

有更快的方法吗?

3 个答案:

答案 0 :(得分:4)

比较我能想到的三种不同方法 -

In [12]: def foo():
   ....:     d = {1:2 , 3:4}
   ....:     d[1] = max(3, d.get(1,0))
   ....:

In [13]: def foo1():
   ....:     d = {1:2, 3:4}
   ....:     if d.get(1,0) < 3:
   ....:         d[1] = 3
   ....:

In [14]: def foo2():
   ....:     d = {1:2, 3:4}
   ....:     d[1] = 3 if d.get(1,0) < 3 else d.get(1)
   ....:

In [15]: %timeit foo()
The slowest run took 4.18 times longer than the fastest. This could mean that an intermediate result is being cached
1000000 loops, best of 3: 1 µs per loop

In [16]: %timeit foo1()
The slowest run took 11.46 times longer than the fastest. This could mean that an intermediate result is being cached
1000000 loops, best of 3: 564 ns per loop

In [17]: %timeit foo2()
The slowest run took 4.79 times longer than the fastest. This could mean that an intermediate result is being cached
1000000 loops, best of 3: 556 ns per loop

In [18]: %timeit foo()
The slowest run took 10.17 times longer than the fastest. This could mean that an intermediate result is being cached
1000000 loops, best of 3: 861 ns per loop

In [19]: %timeit foo1()
The slowest run took 5.90 times longer than the fastest. This could mean that an intermediate result is being cached
1000000 loops, best of 3: 645 ns per loop

In [20]: %timeit foo2()
The slowest run took 8.01 times longer than the fastest. This could mean that an intermediate result is being cached
1000000 loops, best of 3: 523 ns per loop

如果我们相信%timeit的结果似乎是最快的 -

some_dict[k] = new_val if some_dict.get(k, 0) < new_val else some_dict.get(k)

这假设new_val总是大于0,因此我们在else部分不需要some_dict.get(k,0)。尽管如此,但没有太大区别。

答案 1 :(得分:1)

嗯,显而易见的另一种方法是不总是进行赋值,而不是调用额外的函数调用:

if some_dict.get(k, 0) < new_val:
    some_dict[k] = new_val

这实际上是否更快是另一个问题。

答案 2 :(得分:0)

还有另一种方法尚未提及:

get = d.get
val = get(k, 0)
d[k] = (val, new_val)[val<new_val]

此方法仅播放内存,而不使用分支。

速度有多快?嗯,它应该很快。

get = d.get

将指针保存在字典外部,以便更快地访问该方法。

您也可以使用dict.setdefault()。 这是一个有趣的小方法。

请参阅help(dict.setdefault)。