Namedtuple problem #32.11.d

Deborah Swanson python at deborahswanson.net
Tue Jun 6 15:57:39 EDT 2017


Peter Otten wrote, on Tuesday, June 06, 2017 1:31 AM
> 
> Deborah Swanson wrote:
> 
> >  [{Record}(r0=v0, r1=v1,...,r10=v10,r11='',...r93='')
>   
> Lovely column names ;)

Not very sexy names, I agree ;) 
The columns do have real names. The first 10 are friendly and
semi-friendly names, but the names for the 28 triplets are each
comprised of a root word with a prefix and a suffix, so they're quite
cryptic. Copying them all out would have overwhelmed the first half of
this message and obscured that the columns are divided into two groups,
each group needing a different programmatic approach. So I went with
simple numerically based names that permitted the use of ellipses.

But I think you knew this, and were just teasing ;)
 
> > Because, I can't say
> > 
> > r = r._replace(getattr(r, column) = data)
> 
> When r is mutable, i. e. *not* a namedtuple, you can write
> 
> setattr(r, column, data)
> 
> This assumes column is the column name (a string) -- and it will
overwrite 
> the current value of the attribute.

I'll have to try this using recordclass instead of namedtuple. After the
import, it's only a one line change to transform namedtuple code to
recordclass code.

Change 
	Record = namedtuple("Record", fieldnames)
to 
	Record = recordclass("Record", fieldnames)

and recordclass is written so elegantly that your namedtuple code
functions exactly the same as recordclass code as it did when it was
namedtuple code. (Well, I've only tried it in this one case, but from
reading the recordclass tutorial, I think that will hold up to be true
in most if not all cases.)

So you can easily switch back and forth between them.
 
> If you need the current value as part of a calculation you can access
it 
> with getattr(). E. g. if you want to multiply columns r.foo and r.bar
by a 
> value stored in data:
> 
> def update_record(record, columnname, data):
>     newval = getattr(r, columnname) * data
>     setattr(r, columnname, newval)
> 
> columns = ["foo", "bar"]
> data = 42
> 
> for record in records:
>     for column in columns:
>         update_record(record, column, data)

Most excellent, and I'll have to also try this. I'd never seen getattr
or setattr last time we attempted a namedtuple problem, and even though
I understand them a little better now, I still haven't made a lot of
headway in using them. This will be a good chance to see another way
they can be successfully used, so thank you.
 
> For immutable (namedtuple) rows this has to be changed:
> 
> def updated_record(record, columname, data):
>     newval = getattr(r, columnname) * data
>     return r._update(**{columnname: newval})
> 
> for index, record in enumerate(records):
>     for column in columns:
>         record = updated_record(record, column, data)
>     records[index] = record

Again, most excellent, and I'll try this too. It is one of my primary
goals to learn what standard Python can do, both for it's own sake, and
so I can more fully appreciate what the packages and extensions have to
offer. So a possible solution using native namedtuple code is much
appreciated.

> There are various approaches to make this clearer. As I have a vage
memory 
> of recommending `dict`s before I won't do it again...

And I'm truly sorry your recommendation of several dict solutions last
time around baffled me so profoundly. The online introductory courses in
Python that I'd taken only gave us a very cursory introduction to simple
uses of dicts, and I had no idea that they could be used in so many
complex and mysterious ways. But I've been working with dicts, and
particularly with your examples of their use. I think I have a much
better understanding of most of your examples now, but not all.

I also recall your mentioning that you would solve the previous
namedtuple problem I asked about with dicts throughout, bypassing
namedtuples altogether. I was quite intrigued with that idea, but since
I lack sufficient experience with dicts I was reluctant to ask you to
elaborate.

I suspect you are hinting at a dicts-throughout solution here, but I can
only guess what you might mean.

I would be very interested in seeing what you have in mind, if you are
so inclined. Though I think I would need some time to work with it and
understand it better before I attempted to reply.

Thank you again for your continued help with this class of problems. And
I think it would be best for me to simply take in what you have to say
and work with it for while, rather than trying to interact while my
ideas about what may be going on are still fuzzy and I'm easily
confused. Just trying to spare us both some needless frustration ;)

Deborah




More information about the Python-list mailing list