Keeping a list of records with named fields that can be updated
Peter Otten
__peter__ at web.de
Mon Dec 19 13:29:20 EST 2022
On 18/12/2022 16:44, songbird wrote:
> Peter Otten wrote:
> ...
>> While I think what you need is a database instead of the collection of
>> csv files the way to alter namedtuples is to create a new one:
>>
>>>>> from collections import namedtuple
>>>>> Row = namedtuple("Row", "foo bar baz")
>>>>> row = Row(1, 2, 3)
>>>>> row._replace(bar=42)
>> Row(foo=1, bar=42, baz=3)
>
> namedtuple is easier to use as that will use the csv and
> csvreader and create the records without me having to do any
> conversion or direct handling myself. it's all automagically
> done. my initial version works, but i'd like it to be a bit
> more elegant and handle descriptions it hasn't seen before
> in a more robust manner.
>
>
>> An alternative would be dataclasses where basic usage is just as easy:
>>
>>>>> from dataclasses import make_dataclass
>>>>> Row = make_dataclass("Row", "foo bar baz".split())
>>>>> row = Row(1, 2, 3)
>>>>> row
>> Row(foo=1, bar=2, baz=3)
>>>>> row.bar = 42
>>>>> row
>> Row(foo=1, bar=42, baz=3)
>
> i do like that i can directly reference each field in a
> dataclass and not have to specify a _replace for each change.
>
> is there an easy way to convert from namedtuple to dataclass?
> i can see there is a _asdict converter, but don't really like
> how that turns out as then i have to do a bunch of:
> rec['fieldname'] = blah
>
> rec.fieldname is much easier to understand.
I recommend that you use a dataclass /instead/ of a namedtuple, not
both. However, for a dataclass with the same fields in the same order as
in your namedtuple the conversion is trivial:
Create compatible namedtuple and dataclass types:
>>> NTRow = namedtuple("NTRow", ["alpha", "beta", "gamma"])
>>> DCRow = make_dataclass("DCRow", NTRow._fields)
Build the namedtuple:
>>> ntrow = NTRow(1, "two", 3.0)
>>> ntrow
NTRow(alpha=1, beta='two', gamma=3.0)
Convert to dataclass:
>>> dcrow = DCRow(*ntrow)
>>> dcrow
DCRow(alpha=1, beta='two', gamma=3.0)
More information about the Python-list
mailing list