magical expanding hash
James Stroud
jstroud at ucla.edu
Tue Jan 17 21:28:02 EST 2006
braver wrote:
> Thanks, James! This is really helpful.
>
> : It would take a lot of coding to make that << work right. Better is
> the pythonic
> :
> : m[key] = [value]
> :
> : Its really only one more keystroke than
> :
> : m[key] << value
>
> But it's only for the first element, right? I'd have to say
> meh[key1]...[keyN].append(elem2) after that, while I want an operator
> to look the same.
Yes, being explicit is only for the first element with the "<<". If you
use the lshiftinglist I provided, you could easily do
class lshiftinglist(list):
def __lshift__(self, value):
list.append(self, value)
class meh(dict):
def __getitem__(self, item):
return dict.setdefault(self, item, meh())
def __getattr__(self, attr):
return self.ga(attr)
def __lshift__(self, value):
print "You are thinking of '%s'." % value
def __iadd__(self, other):
# don't try this on a populated meh!!!!!
return other
m = meh()
m['fred'] = lshiftinglist([18])
m['fred'] << 25
m['barney'] += 1
m['barney'] += 1
print m # {'barney': 2, 'fred': [18, 25]}
And so-on. More pythonic, of course is
m['fred'] = [18]
m['key'].append(25)
m['barney'] = 1
m['barney'] += 1
Now the reason "m['barney'] += 1" works in the former is becasue "+="
actually returns a value to which the name on the left gets re-assigned.
"<<" does not work this way, so it can't be done as easily.
You might want to make a named method that thinks for you. The resulting
code is less terse but more clear (i.e. pythonic):
def meh_append(ameh, key, value):
if not ameh.has_key(key):
ameh[key] = [value]
else:
ameh[key].append(value)
def meh_addleaf(ameh, key, value={}):
if value == {}:
ameh[key] = {}
else:
ameh[key] = value
m = meh()
meh_addleaf(m['bob'], 'carol', None)
meh_append(m['ted'], 'alice', 14)
meh_append(m, 'fred', 1)
meh_append(m, 'fred', 2)
print m # {'bob': {'carol': None},
# 'ted': {'alice': [14]}, 'fred': [1, 2]}
But now its getting very pythonic. And the only magic we need is the
original __getattr__ modification, which we could find a way of
eliminating if we tried.
James
More information about the Python-list
mailing list