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: Dictionary initialization
Type: behavior Stage: resolved
Components: Documentation Versions: Python 3.6
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: docs@python Nosy List: Aditya Sane, docs@python, josh.r, rhettinger
Priority: normal Keywords: patch

Created on 2019-04-24 19:49 by Aditya Sane, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
DictionaryBug.py Aditya Sane, 2019-04-24 19:49 Unexpected Dictionary Initialization behavior
Pull Requests
URL Status Linked Edit
PR 12974 merged rhettinger, 2019-04-26 17:19
Messages (3)
msg340805 - (view) Author: Aditya Sane (Aditya Sane) Date: 2019-04-24 19:49
When initializing a dictionary with dict.fromkeys, if an object is used as initial value, then the value is taken by reference instead of by value.
This results in incorrect behavior since Python doesn't have "by reference" or pointers by default.
Attached file shows an example and one work-around.
msg340807 - (view) Author: Josh Rosenberg (josh.r) * (Python triager) Date: 2019-04-24 20:13
This is the same basic problem seen with sequence multiplication, mutable default arguments to a function, etc. It's not going to change though; the documentation says it "Create a new dictionary with keys from iterable and values set to value." "set to value" doesn't allow for implicit copy operations (shallow or deep), and trying to support it would slow fromkeys and violate the normal expectations for functions that reuse an input argument. Essentially, the problem you have is one of expectations; the behavior is correct, but perhaps the documentation could be clearer.

In any event, the general solution to your problem is a dict comprehension (or for dict subclasses, passing a generator expression to the subclass constructor), replacing the incorrect:

    dict.fromkeys(iterable, [])

with the similarly concise/straightforward:

    {k: [] for k in iterable}

or (for general use, where dict can be changed to a dict subclass):

    dict((k, []) for k in iterable)

I've marked this as a documentation bug if someone wants to take a stab at making the behavior more clear.
msg341024 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2019-04-28 07:22
New changeset da63b321f63b697f75e7ab2f88f55d907f56c187 by Raymond Hettinger in branch 'master':
bpo-36715: Add usage note for dict.fromkeys() (GH-12974)
https://github.com/python/cpython/commit/da63b321f63b697f75e7ab2f88f55d907f56c187
History
Date User Action Args
2022-04-11 14:59:14adminsetgithub: 80896
2019-04-28 07:23:07rhettingersetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2019-04-28 07:22:49rhettingersetnosy: + rhettinger
messages: + msg341024
2019-04-26 17:19:46rhettingersetkeywords: + patch
stage: patch review
pull_requests: + pull_request12901
2019-04-25 01:47:38methanesetnosy: - methane
2019-04-25 01:10:33xtreaksetnosy: + methane
2019-04-24 20:13:34josh.rsetnosy: + docs@python, josh.r
messages: + msg340807

assignee: docs@python
components: + Documentation
2019-04-24 19:49:57Aditya Sanecreate