classification
Title: Unclear why dict unpacking cannot be used in dict comprehension
Type: enhancement Stage: resolved
Components: Versions:
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: PartlyFluked, steven.daprano
Priority: normal Keywords:

Created on 2020-12-23 11:21 by PartlyFluked, last changed 2020-12-23 11:51 by steven.daprano. This issue is now closed.

Messages (2)
msg383641 - (view) Author: Luke Davis (PartlyFluked) Date: 2020-12-23 11:21
Why am I unable to do:

dict = { **sub_dict for sub_dict in super_dict.values() }

which throws: "dict unpacking cannot be used in dict comprehension"

Whereas the equivalent code below doesn't throw any errors?:

dict = {}
for sub_dict in super_dict.values():
    dict = { **dict, **sub_dict }

Am I wrong in thinking the first and second block of code should do the same thing behind the scenes?
msg383644 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2020-12-23 11:51
They don't do the same thing.

The dict comprehension requires a single key:value pair per loop. It accumulates values into a single dict. Try this:

    d = {}
    for key, value in items:
        print(id(d))
        d[key] = value

The ID doesn't change because it is the same dict each time.

Unpacking a dict doesn't produce a single key:value pair, except maybe by accident, so it is not usable in a dict comprehension.

Your second example doesn't modify a single dict, it **replaces** it with a new dict each time.

    d = {}
    for sub_dict in super_dict.values():
        print(id(d))
        d = { **d, **sub_dict }

The IDs will change through the loop as d gets replaced with a new dict each time. So this is not equivalent to a comprehension.

Also, the second would also be very inefficient. It unpacks the existing dict, then packs the values into a new dict, then unpacks it again, then repacks it into yet another dict, and so on.

Better:

    d = {}
    for sub_dict in super_dict.values():
        d.update(sub_dict)

But that's not equivalent to a dict comprehension either.
History
Date User Action Args
2020-12-23 11:51:42steven.dapranosetstatus: open -> closed

nosy: + steven.daprano
messages: + msg383644

resolution: not a bug
stage: resolved
2020-12-23 11:21:19PartlyFlukedcreate