Using namedtuples field names for column indices in a list of lists

Deborah Swanson python at deborahswanson.net
Mon Jan 9 07:25:27 EST 2017


Steve D'Aprano wrote, on January 09, 2017 3:40 AM
> 
> On Mon, 9 Jan 2017 09:57 pm, Deborah Swanson wrote:
> 
> [...]
> > I think you are replying to my question about sorting a 
> namedtuple, in 
> > this case it's called 'records'.
> > 
> > I think your suggestion works for lists and tuples, and probably 
> > dictionaries. But namedtuples doesn't have a sort function.
> 
> Tuples in general (whether named or not) represent structs or 
> records, where the position of the item is significant. It 
> doesn't usually make sense to sort individual elements of a 
> record or tuple:
> 
> Before sorting: Record(name='George', spouse='', 
> position='Accountant') After sorting:  Record(name='', 
> spouse='Accountant', position='George')
> 
> 
> I think what you want to do is sort a list of records, not 
> each record itself. Or possibly you want to reorder the 
> columns, in which case the easiest way to do that is by 
> editing the CSV file in LibreOffice or Excel or another 
> spreadsheet application.
> If you have a list of records, call .sort() on the list, not 
> the individual records. 
> 

I want to sort a nametuple of records.

I could convert it to a list easy enough, with:

recs = list(records)

and then use the column copying and deleting method I described in my
previous post and use mergesort. This would give me exactly what I had
in my original code, and it would be ok. There's only one step after the
mergesort, and I could do it without the namedtuple, although I'd have
to count column indices for that section, and rewrite them whenever the
columns changed, which was what my original 2-letter codes and the
conversion to namedtuples were both meant to avoid.

So all in all, the best thing would be if there's a way to sort records
as a namedtuple. 


> But if I am wrong, and you absolutely must sort the fields of 
> each record, call the sorted() function, which will copy the 
> fields into a list and sort the list. That is:
> 
> alist = sorted(record)
> 
> -- 
> Steve
> "Cheer up," they said, "things could be worse." So I cheered 
> up, and sure enough, things got worse.

I'm not sure what you mean by sorting the fields of each record. I want
all the rows in records sorted by the Description and Date in each
record.

alist = sorted(record)

looks like it sorts one record, by what? An alphanumeric ordering of all
the fields in record?  That would be beyond useless for my purposes.

It's possible sorted() will work on namedtuples. Stackoverflow has an
example:

from operator import attrgetter
from collections import namedtuple

Person = namedtuple('Person', 'name age score')
seq = [Person(name='nick', age=23, score=100),
       Person(name='bob', age=25, score=200)]
# Sort list by name
sorted(seq, key=attrgetter('name'))
# Sort list by age
sorted(seq, key=attrgetter('age'))

So apparently it's done, and it's a keyed sort too. Although what
they're sorting is a list of namedtuples, which may or may not work on a
single namedtuple made of row (record) namedtuples. I'll definitely try
it tomorrow.

Know any way to convert a list back into a namedtuple? I suppose I could
go through all the steps used at the beginning to make records, but that
seems a waste if there's any way at all to sort the namedtuple without
converting it into a list.

Thanks Steven! Maybe sorted() is my friend here.  (haha, and maybe not.)

Deborah



More information about the Python-list mailing list