Skip to main content
Remove unnecessary spaces
Source Link
Benjamin Loison
  • 5.5k
  • 4
  • 18
  • 37
 newdict = {**dict1, **dict2, **dict3}
 (newdict := dict1.copy()).update(dict2), newdict.update(dict3)
 (newdict := dict1.copy()).update(dict2) or newdict.update(dict3)
 newdict = {**dict1, **dict2, **dict3}
 (newdict := dict1.copy()).update(dict2), newdict.update(dict3)
 (newdict := dict1.copy()).update(dict2) or newdict.update(dict3)
newdict = {**dict1, **dict2, **dict3}
(newdict := dict1.copy()).update(dict2), newdict.update(dict3)
(newdict := dict1.copy()).update(dict2) or newdict.update(dict3)
Include the trick to make the expression as a whole evaluate to the new dictionary, not just perform both copy and update as a one-liner that doesn't evaluate to the new dict
Source Link
ShadowRanger
  • 151.7k
  • 12
  • 200
  • 295

while behaving identically in every way. If you must also return the resulting dict (you asked for an expression returning the dict; the above creates and assigns to newdict, but doesn't return it, so you couldn't use it to pass an argument to a function as is, a la myfunc((newdict := dict1.copy()).update(dict2))), then just add or newdict to the end (since update returns None, which is falsy, it will then evaluate and return newdict as the result of the expression):

(newdict := dict1.copy()).update(dict2) or newdict

The unpacking approach is clearer (to anyone who knows about generalized unpacking in the first place, which you should), doesn't require a name for the result at all (so it's much more concise when constructing a temporary that is immediately passed to a function or included in a list/tuple literal or the like), and is almost certainly faster as well, being (on CPython) roughly equivalent to:

while behaving identically in every way.

The unpacking approach is clearer (to anyone who knows about generalized unpacking in the first place, which you should), and is almost certainly faster as well, being (on CPython) roughly equivalent to:

while behaving identically in every way. If you must also return the resulting dict (you asked for an expression returning the dict; the above creates and assigns to newdict, but doesn't return it, so you couldn't use it to pass an argument to a function as is, a la myfunc((newdict := dict1.copy()).update(dict2))), then just add or newdict to the end (since update returns None, which is falsy, it will then evaluate and return newdict as the result of the expression):

(newdict := dict1.copy()).update(dict2) or newdict

The unpacking approach is clearer (to anyone who knows about generalized unpacking in the first place, which you should), doesn't require a name for the result at all (so it's much more concise when constructing a temporary that is immediately passed to a function or included in a list/tuple literal or the like), and is almost certainly faster as well, being (on CPython) roughly equivalent to:

added 177 characters in body
Source Link
ShadowRanger
  • 151.7k
  • 12
  • 200
  • 295

where using assignment expressions won't scale like that; the closest you could get would be to comma-separate:

 (newdict := dict1.copy()).update(dict2), newdict.update(dict3)

or without the additional updates (which would make a temporary tupletuple of the None results froms, but with truthiness testing of each updateNone, thrown away immediately after) result:

 (newdict := dict1.copy()).update(dict2), or newdict.update(dict3)

either of which is obviously much uglier, on top of theand includes further inefficiencies (either a wasted temporary tuple of Nones for comma separation, or pointless truthiness testing of each update's None return for or separation).

where using assignment expressions won't scale like that; the closest you could get would be to comma-separate the additional updates (which would make a temporary tuple of the None results from each update, thrown away immediately after):

 (newdict := dict1.copy()).update(dict2), newdict.update(dict3)

which is obviously much uglier, on top of the wasted temporary tuple.

where using assignment expressions won't scale like that; the closest you could get would be:

 (newdict := dict1.copy()).update(dict2), newdict.update(dict3)

or without the temporary tuple of Nones, but with truthiness testing of each None result:

 (newdict := dict1.copy()).update(dict2) or newdict.update(dict3)

either of which is obviously much uglier, and includes further inefficiencies (either a wasted temporary tuple of Nones for comma separation, or pointless truthiness testing of each update's None return for or separation).

Source Link
ShadowRanger
  • 151.7k
  • 12
  • 200
  • 295
Loading