【问题标题】:Dictionary value initialization on lookup [duplicate]查找时的字典值初始化[重复]
【发布时间】:2014-09-30 22:27:33
【问题描述】:

考虑以下几点:

mylist = ['a','b','c','d']
mydict = {}
for val in mylist:
    if val not in mydict:
        mydict[val] = []
    mydict[val].append(1)

有没有办法避免双重查找(“val in mydict”和“mydict[val]”)?

注意 - 我尝试使用默认返回值(即mydict.get(val, []).append(1)),但新列表实际上并未在字典中注册为键的值。例如:

mydict = {}
mydict.get('not_in_dict','default')
mydict

返回{}。就我而言,我想要返回 {'not_in_dict' : 'default'} 的东西。

或者这里的正确答案是我不应该担心双重查找? (例如“冷静,伙计,如果你不需要,就不要优化”或“python 很棒,它已经解决了这个问题”)。

我正在使用 python 3.4。

【问题讨论】:

  • @Ashwini - 感谢您指出重复的问题。那里的答案正是我想要的。

标签: python python-3.x


【解决方案1】:

您可以使用dict.setdefault

mylist = ['a','b','c','d']
mydict = {}
for val in mylist:
    mydict.setdefault(val,[])
    mydict[val].append(1)

或者使用collections.defaultdict,效率更高

from collections import defaultdict
mylist = ['a','b','c','d']
mydict = defaultdict(list)
for val in mylist:
    mydict[val].append(1)


In [14]: mylist = ['a','b','c','d']    
In [15]: mydict = {}    
In [16]: %%timeit
   ....: for val in mylist:
   ....:     mydict.setdefault(val,[])
   ....:     mydict[val].append(1)
   ....: 
1000000 loops, best of 3: 1.51 µs per loop

In [18]: mydict = defaultdict(list)
In [19]: %%timeit
   ....: for val in mylist:
   ....:     mydict[val].append(1)
   ....: 
1000000 loops, best of 3: 603 ns per loop

【讨论】:

  • 您的示例似乎仍在进行两次查找:mydict.setdefault(val,[]),然后再次使用 mydict[val].append(1)。链接两个命令时时间是否会改变:mydict.setdefault(val,[]).append(1)?
  • 最有效的解决方案是defaultdict,您的原始代码紧随其后,检查密钥是否存在是恒定时间,因此检查密钥是否存在非常便宜,因此您自己的代码是相当有效。
  • 我想答案真的是这并不重要。我敢肯定那里有一个关于过早优化是万恶之源的python引用。 :)
  • 当然,defaultdict 是一个方便的工具,但值得学习。就优化而言,我总是让我的代码完成并正常工作,然后在需要时担心优化。
【解决方案2】:
from collections import defaultdict

mydict = defaultdict(list)
mydict['not in dict'] = 'foo'

【讨论】:

    猜你喜欢
    • 2017-11-15
    • 2018-07-14
    • 2018-05-02
    • 1970-01-01
    • 2018-10-22
    • 2016-02-14
    • 2014-09-23
    • 2023-03-30
    • 1970-01-01
    相关资源
    最近更新 更多