Namedtuples: some unexpected inconveniences

Peter Otten __peter__ at web.de
Sat Apr 15 03:43:49 EDT 2017


Deborah Swanson wrote:

> I know it's your "ugly" answer, but can I ask what the '**' in
> 
> fix = {label: max(values, key=len)}
> group[:] = [record._replace(**fix) for record in group]
> 
> means? 

d = {"a": 1, "b": 2}
f(**d)

is equivalent to

f(a=1, b=2)

so ** is a means to call a function with keyword arguments when you want to 
decide about the *names* at runtime. Example:

>>> def f(a=1, b=2):
...     print("a =", a)
...     print("b =", b)
...     print()
... 
>>> for d in [{"a": 10}, {"b": 42}, {"a": 100, "b": 200}]:
...     f(**d)
... 
a = 10
b = 2

a = 1
b = 42

a = 100
b = 200

Starting from a namedtuple `record`

record._replace(Location="elswhere")

creates a new namedtuple with the Location attribute changed to "elsewhere", 
and the slice [:] on the left causes all items in the `groups` list to be 
replaced with new namedtuples,

group[:] = [record._replace(Location="elsewhere") for record in group]

is basically the same as

tmp = group.copy()
group.clear()
for record in tmp:
    group.append(record_replace(Location="elsewhere"))

To support not just Location, but also Kind and Notes we need the double 
asterisk.



More information about the Python-list mailing list