Python 2.5中增加的collections.defaultdict极大地减少了对dict的setdefault方法的需求。这个问题是为了我们的集体教育:
在今天的Python 2.6/2.7中,setdefault在哪些方面仍然有用? setdefault的哪些流行用例被collections.defaultdict所取代?
Python 2.5中增加的collections.defaultdict极大地减少了对dict的setdefault方法的需求。这个问题是为了我们的集体教育:
在今天的Python 2.6/2.7中,setdefault在哪些方面仍然有用? setdefault的哪些流行用例被collections.defaultdict所取代?
当前回答
[编辑]大错特错!setdefault总是会触发long_computation,因为Python很急切。
扩展塔特尔的答案。对我来说,最好的用例是缓存机制。而不是:
if x not in memo:
memo[x]=long_computation(x)
return memo[x]
这需要3行和2到3次查找,我很乐意这样写:
return memo.setdefault(x, long_computation(x))
其他回答
Defaultdict在默认值是静态时很好,就像一个新列表,但如果它是动态的,就不那么好了。
例如,我需要一个字典来映射字符串到唯一的整数。Defaultdict (int)将始终使用0作为默认值。同样,defaultdict(intGen())总是生成1。
相反,我用了一个普通的词典:
nextID = intGen()
myDict = {}
for lots of complicated stuff:
#stuff that generates unpredictable, possibly already seen str
strID = myDict.setdefault(myStr, nextID())
注意这个词典。get(key, nextID())是不够的,因为我需要能够在以后引用这些值。
intGen是我构建的一个小类,它自动递增int并返回它的值:
class intGen:
def __init__(self):
self.i = 0
def __call__(self):
self.i += 1
return self.i
如果有人有办法做到这一点与defaultdict,我很乐意看到它。
setdefault()的不同用例是当您不想覆盖已经设置的键的值时。Defaultdict会覆盖,而setdefault()不会。对于嵌套字典,更常见的情况是,只有在键尚未设置时才设置默认值,因为您不想删除当前子字典。这就是使用setdefault()的时候。
使用defaultdict的示例:
>>> from collection import defaultdict()
>>> foo = defaultdict()
>>> foo['a'] = 4
>>> foo['a'] = 2
>>> print(foo)
defaultdict(None, {'a': 2})
Setdefault不会覆盖:
>>> bar = dict()
>>> bar.setdefault('a', 4)
>>> bar.setdefault('a', 2)
>>> print(bar)
{'a': 4}
我通常使用setdefault作为关键字参数字典,例如在这个函数中:
def notify(self, level, *pargs, **kwargs):
kwargs.setdefault("persist", level >= DANGER)
self.__defcon.set(level, **kwargs)
try:
kwargs.setdefault("name", self.client.player_entity().name)
except pytibia.PlayerEntityNotFound:
pass
return _notify(level, *pargs, **kwargs)
它非常适合在包装器中围绕接受关键字参数的函数调整参数。
[编辑]大错特错!setdefault总是会触发long_computation,因为Python很急切。
扩展塔特尔的答案。对我来说,最好的用例是缓存机制。而不是:
if x not in memo:
memo[x]=long_computation(x)
return memo[x]
这需要3行和2到3次查找,我很乐意这样写:
return memo.setdefault(x, long_computation(x))
当我想要OrderedDict中的默认值时,我使用setdefault()。没有一个标准的Python集合可以同时做到这两点,但是有一些方法可以实现这样的集合。