繁体   English   中英

dict 和 collections.defaultdict 有什么区别?

[英]What is the difference between dict and collections.defaultdict?

我正在查看 Peter Norvig 关于如何编写简单拼写检查器的代码 一开始,他使用此代码将单词插入字典。

def train(features):
    model = collections.defaultdict(lambda: 1)
    for f in features:
        model[f] += 1
    return model

Python 字典和这里使用的字典有什么区别? 另外, lambda是干什么用的? 我在这里查看了 API 文档,它说 defaultdict 实际上是从 dict 派生的,但是如何决定使用哪一个?

不同之处在于,如果尚未设置该键,则defaultdict将“默认”一个值。 如果您没有使用defaultdict ,则必须检查该键是否存在,如果不存在,请将其设置为您想要的。

lambda 正在为默认值定义工厂。 每当需要默认值时,都会调用 function 。 您可以假设有一个更复杂的默认 function。

Help on class defaultdict in module collections:

class defaultdict(__builtin__.dict)
 |  defaultdict(default_factory) --> dict with default factory
 |  
 |  The default factory is called without arguments to produce
 |  a new value when a key is not present, in __getitem__ only.
 |  A defaultdict compares equal to a dict with the same items.
 |  

(来自help(type(collections.defaultdict()))

{}.setdefault本质上类似,但接受一个值而不是工厂 function。 如果该值尚不存在,则用于设置该值……不过,这有点不同。

礼貌:- https://shirishweb.wordpress.com/2017/05/06/python-defaultdict-versus-dict-get/

使用普通字典

d={}
d['Apple']=50
d['Orange']=20
print(d['Apple'])
print(d['Grapes'])# This gives Key Error

我们也可以通过在普通字典中使用默认值来避免这个 KeyError,让我们看看如何做到这一点

d={}
d['Apple']=50
d['Orange']=20
print(d['Apple'])
print(d.get('Apple'))
print(d.get('Grapes',0)) # DEFAULTING

使用默认字典

from collections import defaultdict
d = defaultdict(int) ## inside parenthesis we say what should be the default value.
d['Apple']=50
d['Orange']=20
print(d['Apple'])
print(d['Grapes']) ##→ This gives Will not give error

使用用户定义的 function 来默认值

from collections import defaultdict
def mydefault():
        return 0

d = defaultdict(mydefault)
d['Apple']=50
d['Orange']=20
print(d['Apple'])
print(d['Grapes'])

概括

  1. 普通字典中的默认值视具体情况而定,在默认字典中,我们可以以一般方式提供默认值

  2. 通过 defaultdict 使用默认值的效率是使用普通 dict 进行默认值的两倍。 您可以参考以下链接以更好地了解此性能测试https://shirishweb.wordpress.com/2017/05/06/python-defaultdict-versus-dict-get/

如果您对缺少的键有一些有意义的默认值并且不想明确处理它们,请使用 defaultdict。

defaultdict 构造函数将 function 作为参数,并使用该 function 构造一个值。

lambda: 1

与执行此操作的无参数 function f 相同

def f():
 return 1

我忘记了 API 以这种方式设计的原因,而不是将值作为参数。 如果我设计了defaultdict接口,会稍微复杂一些,缺失值创建function会把缺失的key作为参数。

让我们深入了解 Python 字典和 Python defaultdict() class

Python 字典

Dict 是 Python 中可用的数据结构之一,它允许以键值对的形式存储数据。

例子:

d = {'a': 2, 'b': 5, 'c': 6}

字典问题

除非您遇到丢失的键,否则字典会很好地工作。 假设您正在寻找字典中没有值的键值对 - 那么您可能会遇到KeyError问题。 像这样的东西:

d = {'a': 2, 'b': 5, 'c': 6}
d['z']  # z is not present in dict so it will throw a error

你会看到这样的东西:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
    d['z'] 
KeyError: 'z'

解决上述问题

为了克服上述问题,我们可以使用不同的方法:

使用内置函数

setdefault

如果key在字典中,则返回其值。 如果不是,则插入一个值为default的键并返回default default默认为None

>>> d = {'a' :2, 'b': 5, 'c': 6}
>>> d.setdefault('z', 0)
0  # returns 0 
>>> print(d)  # add z to the dictionary
{'a': 2, 'b': 5, 'c': 6, 'z': 0}

get

如果键在字典中,则返回key的值,否则返回default 如果未给出默认值,则默认为None ,因此此方法永远不会引发KeyError

>>> d = {'a': 2, 'b': 5, 'c': 6}
>>> d.get('z', 0)
0  # returns 0 
>>> print(d)  # Doesn't add z to the dictionary unlike setdefault
{'a': 2, 'b': 5, 'c': 6}

以上2种方法是解决我们问题的方法。 它永远不会引发KeyError 除了以上2种方法,Python还有一个collections模块可以解决这个问题。 让我们深入挖掘 collections 模块中的defaultdict

defaultdict

defaultdict可以在 Python 的 collections 模块中找到。 您可以使用它:

from collections import defaultdict

d = defaultdict(int)

defaultdict构造函数将default_factory作为可调用的参数。 例如,这可以是:

  • int :默认为 integer 值为0

  • str : 默认为空字符串""

  • list : 默认为空列表[]

代码:

from collections import defaultdict

d = defaultdict(list)
d['a']  # access a missing key and returns an empty list
d['b'] = 1 # add a key-value pair to dict
print(d)

output 将是defaultdict(<class 'list'>, {'b': 1, 'a': []})

defaultdictget()setdefault()方法的工作方式相同,那么什么时候使用它们呢?

何时使用get()

如果您特别需要在没有KeyError的情况下返回某个键值对并且它不应该在字典中更新 - 那么dict.get是您的正确选择。 它返回您指定的默认值,但不修改字典。

何时使用setdefault()

如果您需要使用默认键值对修改原始字典 - 那么setdefault是正确的选择。

何时使用defaultdict

setdefault方法可以使用defaultdict来实现,但不是每次都在setdefault中提供默认值,我们可以在defaultdict中一次完成。 此外, setdefault可以选择为键提供不同的默认值。 两者都有自己的优势,具体取决于用例。

在效率方面:

defaultdict > setdefault()get()

defaultdictget()快 2 倍!

你可以在这里查看结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM