[Tutor] appending/updating values dict key value pairs
Steven D'Aprano
steve at pearwood.info
Sun Jun 23 12:33:20 CEST 2013
On 23/06/13 19:42, Sivaram Neelakantan wrote:
> On Sun, Jun 23 2013,Alan Gauld wrote:
>
>
> [snipped 21 lines]
>
>> But we normally call methods via the object instance rather than the
>> class so simplifying this further we get:
>>
>> b['a'].append('c')
>>
>
> Thanks for the detailed explanation.
>
> I've sort of used a dict of this sort {'a': [1,2,'fff'] } in my
> programs and I've noticed that I've got to unpack the list with
> hardcoded list positions when I retrieve the value of a key.
>
> I think I'd be better off, if I did something of
>
> {'a' : ['foo': 1, 'bar':2, 'offset': 'fff'] }
That won't work; you need to make the inner value a dict using {}, not a list using [].
> wouldn't that be better from a maintainability POV? Are there any
> examples of such? Or is there a 'struct' option for python? I don't
> want to use OO methods for now.
Python doesn't have structs in the sense you mean. (But see below for alternatives.) There is a struct module for working with low-level C-style bytes, ints, doubles etc. but that's not what you want.
In this case, you can stick with nested dicts:
{'a' : {'foo': 1, 'bar':2, 'offset': 'fff'}}
It may be less typing if you use this format:
{'a': dict(foo=1, bar=2, offset='fff'),
'b': dict(foo=2, bar=6, offset='fe0'),
'c': dict(foo=4, bar=9, offset='d02'),
}
Instead of working with dicts, it isn't very hard to create your own struct-like class:
class MyStruct(object):
def __init__(self, foo, bar, offset):
self.foo = foo
self.bar = bar
self.offset = offset
A little tedious, but it only needs to be done once, then:
{'a': MyStruct(1, 2, 'fff'),
'b': MyStruct(2, 6, 'fe0'),
'c': MyStruct(4, 9, 'd02'),
}
The advantage is that you can both read and write the attributes:
s = MyStruct(4, 9, 'd02')
s.foo = 42
print(s.bar)
A third alternative is namedtuple, from the collections module.
from collections import namedtuple
MyStruct = namedtuple('MyStruct', 'foo bar offset')
s = MyStruct(4, 9, 'd02')
print(s.bar)
The advantage here is that namedtuple automatically includes extra "polish", such as printing nicely. The only negative is that namedtuples are immutable: once created, you cannot modify them, you have to create a new one:
# this doesn't work
s.foo = 42
# instead do this:
s = MyStruct(42, s.bar, s.offset)
This is deliberate, not a bug. But if you can live with that limitation of namedtuples, then they are the recommended way to get the equivalent of a Pascal record or C struct. Otherwise just create a quick little class as needed.
--
Steven
More information about the Tutor
mailing list