我已经阅读了python文档中的示例,但仍然不明白这个方法是什么意思。有人能帮帮我吗?下面是python文档中的两个例子
>>> from collections import defaultdict
>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
... d[k] += 1
...
>>> d.items()
[('i', 4), ('p', 2), ('s', 4), ('m', 1)]
and
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
... d[k].append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
参数int和list是干什么用的?
defaultdict的行为可以很容易地使用dict模仿。在每次调用中设置default而不是d[key]。
换句话说,代码:
from collections import defaultdict
d = defaultdict(list)
print(d['key']) # empty list []
d['key'].append(1) # adding constant 1 to the list
print(d['key']) # list containing the constant [1]
等价于:
d = dict()
print(d.setdefault('key', list())) # empty list []
d.setdefault('key', list()).append(1) # adding constant 1 to the list
print(d.setdefault('key', list())) # list containing the constant [1]
唯一的区别是,使用defaultdict时,列表构造函数只被调用一次,而使用dict时。Setdefault会更频繁地调用列表构造函数(但如果确实需要,代码可能会被重写以避免这种情况)。
有些人可能会说这是出于性能考虑,但这个话题是一个雷区。例如,这篇文章展示了使用defaultdict并不会带来很大的性能提升。
在我看来,defaultdict是一个给代码带来更多困惑而不是好处的集合。对我没用,但别人可能不这么认为。
由于这个问题是关于“它是如何工作的”,一些读者可能想了解更多的具体细节。具体来说,问题中的方法是__missing__(key)方法。参见:https://docs.python.org/2/library/collections.html#defaultdict-objects。
更具体地说,这个答案展示了如何以一种实用的方式使用__missing__(key):
https://stackoverflow.com/a/17956989/1593924
为了澄清'callable'的含义,这里有一个交互式会话(来自2.7.6,但也适用于v3):
>>> x = int
>>> x
<type 'int'>
>>> y = int(5)
>>> y
5
>>> z = x(5)
>>> z
5
>>> from collections import defaultdict
>>> dd = defaultdict(int)
>>> dd
defaultdict(<type 'int'>, {})
>>> dd = defaultdict(x)
>>> dd
defaultdict(<type 'int'>, {})
>>> dd['a']
0
>>> dd
defaultdict(<type 'int'>, {'a': 0})
这是defaultdict最典型的用法(除了毫无意义地使用x变量)。你可以使用0作为显式默认值,但不能使用简单的值:
>>> dd2 = defaultdict(0)
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
dd2 = defaultdict(0)
TypeError: first argument must be callable
相反,下面的函数可以工作,因为它传递了一个简单的函数(它动态地创建了一个无参数且总是返回0的无名函数):
>>> dd2 = defaultdict(lambda: 0)
>>> dd2
defaultdict(<function <lambda> at 0x02C4C130>, {})
>>> dd2['a']
0
>>> dd2
defaultdict(<function <lambda> at 0x02C4C130>, {'a': 0})
>>>
并且使用不同的默认值:
>>> dd3 = defaultdict(lambda: 1)
>>> dd3
defaultdict(<function <lambda> at 0x02C4C170>, {})
>>> dd3['a']
1
>>> dd3
defaultdict(<function <lambda> at 0x02C4C170>, {'a': 1})
>>>
字典是一种方便的方式来存储数据,以便以后按名称(键)检索。键必须是唯一的、不可变的对象,通常是字符串。字典中的值可以是任何东西。对于许多应用程序,值是简单类型,如整数和字符串。
It gets more interesting when the values in a dictionary are collections (lists, dicts, etc.) In this case, the value (an empty list or dict) must be initialized the first time a given key is used. While this is relatively easy to do manually, the defaultdict type automates and simplifies these kinds of operations.
A defaultdict works exactly like a normal dict, but it is initialized with a function (“default factory”) that takes no arguments and provides the default value for a nonexistent key.
defaultdict永远不会引发KeyError。任何不存在的键都将获得默认工厂返回的值。
from collections import defaultdict
ice_cream = defaultdict(lambda: 'Vanilla')
ice_cream['Sarah'] = 'Chunky Monkey'
ice_cream['Abdul'] = 'Butter Pecan'
print(ice_cream['Sarah'])
>>>Chunky Monkey
print(ice_cream['Joe'])
>>>Vanilla
下面是另一个关于如何使用defaultdict的例子,我们可以降低复杂性
from collections import defaultdict
# Time complexity O(n^2)
def delete_nth_naive(array, n):
ans = []
for num in array:
if ans.count(num) < n:
ans.append(num)
return ans
# Time Complexity O(n), using hash tables.
def delete_nth(array,n):
result = []
counts = defaultdict(int)
for i in array:
if counts[i] < n:
result.append(i)
counts[i] += 1
return result
x = [1,2,3,1,2,1,2,3]
print(delete_nth(x, n=2))
print(delete_nth_naive(x, n=2))
总之,当您需要字典,并且每个元素的值都应该以默认值开始时,请使用defaultdict。