Using namedtuples field names for column indices in a list of lists
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Sun Jan 8 22:29:51 EST 2017
On Sunday 08 January 2017 20:53, Deborah Swanson wrote:
> Steven D'Aprano wrote, on January 07, 2017 10:43 PM
>>
>> On Sunday 08 January 2017 16:39, Deborah Swanson wrote:
>>
>> > What I've done so far:
>> >
>> > with open('E:\\Coding projects\\Pycharm\\Moving\\Moving
>> 2017 in.csv',
>> > 'r') as infile:
>> > ls = list(csv.reader(infile))
>> > lst = namedtuple('lst', ls[0])
>> >
>> > where 'ls[0]' is the header row of the csv, and it works perfectly
>> > well. 'lst' is a namedtuple instance with each of the
>> column titles as
>> > field names.
>>
>> Are you sure? namedtuple() returns a class, not a list:
>
> Yes. 'ls' is defined as 'list(csv.reader(infile))', so ls[0] is the
> first row from the csv, the header row. 'lst' is the namedtuple.
>
> Perhaps what's puzzling you is that the way I've written it, the list of
> data and the namedtuple are disjoint, and that's the problem.
No, I'm pretty sure that's not the case. I don't have access to your CSV file,
but I can simulate it:
ls = [['Location', 'Date', 'Price'],
['here', '1/1/17', '1234'],
['there', '1/1/17', '5678'],
['everywhere', '1/1/17', '9821']
]
from collections import namedtuple
lst = namedtuple('lst', ls[0])
print(type(lst))
print(lst)
If you run that code, you should see:
<class 'type'>
<class '__main__.lst'>
which contradicts your statement:
'lst' is a namedtuple instance with each of the column
titles as field names.
and explains why you had to access the individual property method `fget`: you
were accessing the *class object* rather than an actual named tuple instance.
The code you gave was:
lst.Location.fget(l)
where l was not given, but I can guess it was a row of the CSV file, i.e. an
individual record. So:
- lst was the named tuple class, a subclass of tuple
- lst.Location returns a property object
- lst.Location.fget is the internal fget method of the property object.
I think Peter Otten has the right idea: create a list of records with something
like this:
Record = namedtuple('Record', ls[0])
data = [Record(*row) for row in ls[1:])
or if you prefer Peter's version:
data = [Record._make(row) for row in ls[1:])
Half the battle is coming up with the right data structures :-)
--
Steven
"Ever since I learned about confirmation bias, I've been seeing
it everywhere." - Jon Ronson
More information about the Python-list
mailing list