Use cases for the 'setdefault' dict method

2019-01-03 00:52发布

The addition of collections.defaultdict in Python 2.5 greatly reduced the need for dict's setdefault method. This question is for our collective education:

  1. What is setdefault still useful for, today in Python 2.6/2.7?
  2. What popular use cases of setdefault were superseded with collections.defaultdict?

16条回答
乱世女痞
2楼-- · 2019-01-03 01:23

I use setdefault frequently when, get this, setting a default (!!!) in a dictionary; somewhat commonly the os.environ dictionary:

# Set the venv dir if it isn't already overridden:
os.environ.setdefault('VENV_DIR', '/my/default/path')

Less succinctly, this looks like this:

# Set the venv dir if it isn't already overridden:
if 'VENV_DIR' not in os.environ:
    os.environ['VENV_DIR'] = '/my/default/path')

It's worth noting that you can also use the resulting variable:

venv_dir = os.environ.setdefault('VENV_DIR', '/my/default/path')

But that's less necessary than it was before defaultdicts existed.

查看更多
不美不萌又怎样
3楼-- · 2019-01-03 01:23

[Edit] Very wrong! The setdefault would always trigger long_computation, Python being eager.

Expanding on Tuttle's answer. For me the best use case is cache mechanism. Instead of:

if x not in memo:
   memo[x]=long_computation(x)
return memo[x]

which consumes 3 lines and 2 or 3 lookups, I would happily write :

return memo.setdefault(x, long_computation(x))
查看更多
迷人小祖宗
4楼-- · 2019-01-03 01:23

I like the answer given here:

http://stupidpythonideas.blogspot.com/2013/08/defaultdict-vs-setdefault.html

In short, the decision (in non-performance-critical apps) should be made on the basis of how you want to handle lookup of empty keys downstream (viz. KeyError versus default value).

查看更多
SAY GOODBYE
5楼-- · 2019-01-03 01:24

As Muhammad said, there are situations in which you only sometimes wish to set a default value. A great example of this is a data structure which is first populated, then queried.

Consider a trie. When adding a word, if a subnode is needed but not present, it must be created to extend the trie. When querying for the presence of a word, a missing subnode indicates that the word is not present and it should not be created.

A defaultdict cannot do this. Instead, a regular dict with the get and setdefault methods must be used.

查看更多
ゆ 、 Hurt°
6楼-- · 2019-01-03 01:24

Theoretically speaking, setdefault would still be handy if you sometimes want to set a default and sometimes not. In real life, I haven't come across such a use case.

However, an interesting use case comes up from the standard library (Python 2.6, _threadinglocal.py):

>>> mydata = local()
>>> mydata.__dict__
{'number': 42}
>>> mydata.__dict__.setdefault('widgets', [])
[]
>>> mydata.widgets
[]

I would say that using __dict__.setdefault is a pretty useful case.

Edit: As it happens, this is the only example in the standard library and it is in a comment. So may be it is not enough of a case to justify the existence of setdefault. Still, here is an explanation:

Objects store their attributes in the __dict__ attribute. As it happens, the __dict__ attribute is writeable at any time after the object creation. It is also a dictionary not a defaultdict. It is not sensible for objects in the general case to have __dict__ as a defaultdict because that would make each object having all legal identifiers as attributes. So I can't foresee any change to Python objects getting rid of __dict__.setdefault, apart from deleting it altogether if it was deemed not useful.

查看更多
Animai°情兽
7楼-- · 2019-01-03 01:24

One drawback of defaultdict over dict (dict.setdefault) is that a defaultdict object creates a new item EVERYTIME non existing key is given (eg with ==, print). Also the defaultdict class is generally way less common then the dict class, its more difficult to serialize it IME.

P.S. IMO functions|methods not meant to mutate an object, should not mutate an object.

查看更多
登录 后发表回答