检查字典键是否存在的最有效方法,如果存在,则处理其值

Lor*_*ABA 19 python performance dictionary

MyDict = {'key1':'value1', 'key2':'value2'}
Run Code Online (Sandbox Code Playgroud)

我可以通过以下几种方式做到:

if 'key1' in MyDict:
       var1 = MyDict['key1']
Run Code Online (Sandbox Code Playgroud)

要么

if MyDict.has_key('key1'):
       var1 = MyDict['key1']
Run Code Online (Sandbox Code Playgroud)

要么

if MyDict['key1']:
    var1=MyDict['key1']
Run Code Online (Sandbox Code Playgroud)

要么

try: 
   var1=MyDict['key1]
except KeyError, e:
   pass
Run Code Online (Sandbox Code Playgroud)

或者我尝试了类似这样的东西,但它在python中不起作用

if v=MyDict.get('key1'):
       var1=v
Run Code Online (Sandbox Code Playgroud)

而我们冷却可能会找到更多可行的方法来做到这一点.哪一个在计算速度方面最有效?

pav*_*orm 36

给你一点基准(ipython):

In [1]: def test_1(d, k):
   ...:     if k in d:
   ...:         var1 = d[k]
   ...:         

In [2]: def test_2(d, k):
   ...:     if d.has_key(k):
   ...:         var1 = d[k]
   ...:         

In [3]: def test_3(d, k):
   ...:     try:
   ...:         var1 = d[k]
   ...:     except KeyError as e:
   ...:         pass
   ...:     

In [4]: def test_4(d, k):
   ...:     if d.get(k):
   ...:         var1 = d[k]
   ...:         

In [5]: my_dict = {'key{}'.format(i): 'value{}'.format(i) for i in range(1000)}

In [6]: key_valid = "key5"

In [7]: key_non_valid = "key"

In [8]: %timeit test_1(my_dict, key_valid)
10000000 loops, best of 3: 172 ns per loop

In [9]: %timeit test_1(my_dict, key_non_valid)
10000000 loops, best of 3: 132 ns per loop

In [10]: %timeit test_2(my_dict, key_valid)
1000000 loops, best of 3: 211 ns per loop

In [11]: %timeit test_2(my_dict, key_non_valid)
10000000 loops, best of 3: 171 ns per loop

In [12]: %timeit test_3(my_dict, key_valid)
10000000 loops, best of 3: 151 ns per loop

In [13]: %timeit test_3(my_dict, key_non_valid)
1000000 loops, best of 3: 1.07 µs per loop

In [14]: %timeit test_4(my_dict, key_valid)
1000000 loops, best of 3: 246 ns per loop

In [15]: %timeit test_4(my_dict, key_non_valid)
10000000 loops, best of 3: 189 ns per loop
Run Code Online (Sandbox Code Playgroud)

结论:构造key in dict通常最快,仅try except在有效密钥的情况下表现优异,因为它不执行if操作.

  • 如果你能确保价值是真实的.`var1 = d.get(k,None); 如果var1:...`更快? (2认同)
  • 我想指出 try: except: 如果密钥无效,则性能最差。1.07 µs > 132 ns。当密钥不存在时差异超过 800ns 和 20ns 支持尝试/除非密钥存在时,我不理解答案的“表现优于”。 (2认同)
  • @Bechma 我刚刚用 60k 个键测试了这个,并尝试了 except 花了 1 秒,而 k in d 花了 61 秒。 (2认同)
  • 请记住,“.has_key”不在 python3.8 或 python3.9 中(对于较旧的 python3,不是 %100) (2认同)