Namedtuples: some unexpected inconveniences

Deborah Swanson python at deborahswanson.net
Wed Apr 12 19:29:15 EDT 2017


Peter Otten wrote, on Wednesday, April 12, 2017 3:15 PM
> 
> Deborah Swanson wrote:
> 
> >> >value = getattr(record, label)
> >>
> >> That should work.
> > 
> > We may agree that it *should* work, by an intuitive grasp of how it 
> > should work, but it doesn't. You get "object has no attribute
'label'.
> 
> Only if the namedtuple 
> 
> (1) does not have a label attribute and
> (2) the value of the name label is the string "label"
> 
> In that case both
> 
> label = "label"
> getattr(record, label)
> 
> and
> 
> record.label
> 
> will fail with the same AttributeError. The problem is *not* the
dynamic 
> access through getattr().

Agreed, it's not getattr's fault. 

It's a small point, but I suspect getattr(record, label) would still
fail, even if label's value is 'label' and only 'label', but what's the
point of having a variable if it will only ever have just one value?

The question would be whether the compiler (interpreter?) would look at 
getattr(record, label), evaluate label and see that there is a field
named 'label', but I suspect it wouldn't take that many steps. It wants
to see recordset.fieldname, and a bare "label" does not reference the
object.

I don't exactly understand your point (2). If the namedtuple does not
have a label attribute, then getattr(record, label) will get the error
whether the name label holds the string 'label' or not. And it wants to
see recordset.fieldname, not just fieldname. But maybe I misunderstood
what you were saying. This stuff is quite loopy to think about, at least
for me it is.

> >> Indeed you cannot change the namedtuple's attributes. Like the 
> >> "normal" tuple it is designed to be immutable. If you want changes
in 
> >> one list (the group) to appear in another (the original records)
you 
> >> need a mutable data type.
> > 
> > Sadly, that does seem to be the correct conclusion here.
> 
> Think hard if you really need the original list.

It's possible you might transform the namedtuple into a mutable type,
and I didn't try that. But it seems like the group-by defaultdict
strategy would have to have a significant performance edge to be worth
it and you wouldn't have any of the namedtuple properties to work with
after the transformation. I also ran into some trouble with your
algorithm that follows making the defaultdict, and I'm not sure what
value there would be in hashing through that. Though I'm certainly
willing to if you are.

It worked to simply stay with the original list of namedtuples to begin
with.

I remain grateful for your introduction to the collections module. What
a neat little package of tools!



More information about the Python-list mailing list