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,在字典中设置默认值(!!)通常是os。环境字典:
# Set the venv dir if it isn't already overridden:
os.environ.setdefault('VENV_DIR', '/my/default/path')
简单点说,是这样的:
# Set the venv dir if it isn't already overridden:
if 'VENV_DIR' not in os.environ:
os.environ['VENV_DIR'] = '/my/default/path')
值得注意的是,你也可以使用结果变量:
venv_dir = os.environ.setdefault('VENV_DIR', '/my/default/path')
但与违约之前相比,这已经不那么必要了。
其他回答
正如大多数答案,state setdefault或defaultdict将允许您在键不存在时设置默认值。然而,我想指出一个关于setdefault用例的小警告。当Python解释器执行时,setdefaultit将始终计算函数的第二个参数,即使该键存在于字典中。例如:
In: d = {1:5, 2:6}
In: d
Out: {1: 5, 2: 6}
In: d.setdefault(2, 0)
Out: 6
In: d.setdefault(2, print('test'))
test
Out: 6
正如你所看到的,即使字典中已经存在2,print也会被执行。如果您计划使用setdefault来进行诸如内存之类的优化,这就变得尤为重要。如果将递归函数调用作为setdefault的第二个参数,则不会从中获得任何性能,因为Python总是递归地调用该函数。
既然提到了内存,一个更好的选择是使用functools。Lru_cache装饰器,如果考虑使用内存增强函数。Lru_cache可以更好地处理递归函数的缓存需求。
我经常使用setdefault,在字典中设置默认值(!!)通常是os。环境字典:
# Set the venv dir if it isn't already overridden:
os.environ.setdefault('VENV_DIR', '/my/default/path')
简单点说,是这样的:
# Set the venv dir if it isn't already overridden:
if 'VENV_DIR' not in os.environ:
os.environ['VENV_DIR'] = '/my/default/path')
值得注意的是,你也可以使用结果变量:
venv_dir = os.environ.setdefault('VENV_DIR', '/my/default/path')
但与违约之前相比,这已经不那么必要了。
当我想要OrderedDict中的默认值时,我使用setdefault()。没有一个标准的Python集合可以同时做到这两点,但是有一些方法可以实现这样的集合。
我通常使用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))