invert dictionary with list &c

anton muhin antonmuhin.REMOVE.ME.FOR.REAL.MAIL at rambler.ru
Fri Nov 28 12:36:17 CET 2003


Des Small wrote:
> Des Small <des.small at bristol.ac.uk> writes:
> 
> 
>>anton muhin <antonmuhin.REMOVE.ME.FOR.REAL.MAIL at rambler.ru> writes:
> 
> [...]
> 
> 
>>This, however, has given me ideas.  It was never concision I wanted
>>but rather redundancy elimination, and the pattern I wanted _can_ be
>>written:
>>
>>def dict_cons(iter, func, default):      
>>    def process_element(d, (k, v)):
>>        val = d.get(k, default)
>>        d.update(dict([[k, func(v, val)]]))
>>        return d
>>    return reduce(process_element, iter, {})
> 
> 
> Or rather:
> 
> def dict_cons(iter, func, default):
>     def process_element(d, (k, v)):
>         d[k] = func(v, d.get(k, default))
>         return d
>     return reduce(process_element, iter, {})
> 
> def count(l):
>     def pair_pad(l): return [(e, ()) for e in  l]
>     return dict_cons(pair_pad(l), lambda k,d: d+1, 0) 
> 
> def invert(d):
>     def invertitems(l):
>         for k,v in l: yield v,k
>     def addtolist(k, l): return l+[k]
>     return dict_cons(invertitems(d.iteritems()),
>                      addtolist, [])
> 
> 
>>Which is not to say that it should be, of course.  
>>Whereupon, we can say:
>>
>>def count(l):
>>    def pair_pad(l): return [(e, ()) for e in  l]
>>    return dict_cons(pair_pad(l), lambda k,d: d+1, 0) 
>>
>>def invert(d):
>>    def invertitems(l): for k,v in l: yield v,k
>>    def addtolist(k, l): return l+[k]
>>    return dict_cons(invertitems(d.iteritems()),
>>                     addtolist, [])
>>
>>Perhaps I'm terminally unpythonic, but I quite like these.
> 
> 
> [...]
> 

Or like this:

def dict_update(iter, func, default, d):
     def process_element(d, e):
         d[e[0]] = func(d.get(e[0], default), *e[1:])
         return d

     return reduce(process_element, iter, d)

def count(l):
     return dict_update(l, lambda x: x + 1, 0, {})

def invert(d):
     return dict_update(
         [(v, k) for k, v in d.iteritems()],
         # In the future (I hope): ((v, k) for k, v in d.iteritems()),
         lambda l, e: l + [e], [], {}
     )

print count(list('aabbbbcc'))

print invert({'A': 'a', 'B': 'b', 'C': 'a'})

regards,
anton.





More information about the Python-list mailing list