This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Add lazy evaluation support for dict.setdefault()
Type: enhancement Stage: resolved
Components: Versions:
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: jimd, rhettinger, serhiy.storchaka
Priority: normal Keywords:

Created on 2017-08-20 05:14 by jimd, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (3)
msg300596 - (view) Author: Jim Dennis (jimd) Date: 2017-08-20 05:14
Code such as mydict.setdefault('eggs', []) will needlessly incur the cost of instantiating a list even when 'eggs' is already a valid key in mydict.  collections.defaultdict will not do this.  detecting and automatically calling "callable" and "type" objects (implicit laziness) would break cases where callables and types are used as first class values.

Add keyword argument: lazy?  Thus mydict.setdefault('eggs',list, lazy=True) would generate a new list only when necessary while the default would still be to append a reference to list (first class) objects).
msg300598 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-08-20 06:08
The advantage of dict.setdefault() is its atomicity. With lazy evaluation of the value it can't be atomic anymore, and can be replaced with the following code:

    if key not in mydict:
        mydict[key] = value

I'm -1 for this change. It increases complexity (both semantical and implementational) of dict.setdefault() and doesn't have significant benefit.
msg300603 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2017-08-20 15:32
-1 from me as well.

The need has already been fulfilled in other ways (defaultdict and __missing__).  I don't think we need yet another way to do it.

Also, I suspect that the benefit of a lazy instantiation would be more than offset by cost of passing in the arguments (global variable lookup for the list builtin, a load constant for True, and the keyword argument processing).

Lastly, I don't like making the signature more complex or further breaking the already loose symmetry with dict.get() and dict.pop().  Likewise, this isn't parallel with other tools that take a default argument such as min(), max(), getattr(), etc.
History
Date User Action Args
2022-04-11 14:58:50adminsetgithub: 75423
2017-08-20 15:37:46serhiy.storchakasetstatus: open -> closed
resolution: rejected
stage: resolved
2017-08-20 15:32:23rhettingersetmessages: + msg300603
2017-08-20 06:08:27serhiy.storchakasetnosy: + rhettinger, serhiy.storchaka
messages: + msg300598
2017-08-20 05:14:06jimdcreate