permuting over nested dicts?

Boris Borcic bborcic at gmail.com
Thu Nov 8 07:37:07 EST 2007


Boris Borcic wrote:
> Christian Meesters wrote:
>> Hoi,
>>
>> I have the following data structure (of variable size actually, to make
>> things simple, just that one):
>> d = {'a': {'x':[1,2,3], 'y':[4,5,6]},
>>      'b': {'x':[7,8,9], 'y':[10,11,12]}}
>> This can be read as a dict of possibilities: The entities 'a' and 'b' 
>> have
>> the parameters 'x' and 'y', each. And d['a']['x'] can be either 1 or 2 or
>> 3. Does anybody know a convenient (and fast) way to permute over all
>> possible nested dicts like
>> {'a': {'x':1, 'y':4},
>>  'b': {'x':7, 'y':10}}
>> and
>> {'a': {'x':2, 'y':4},
>>  'b': {'x':7, 'y':10}}
>> and so forth?
>>
>> Any link or snippet is appreciated.
>>
>> TIA
>> Christian
> 
> def cases(d) :
>     import re
>     bits = re.split('(\[.*?\])',repr(d))
>     vv = [('_%s' % k, ' for _%s in %s' % (k,v))
>             for k,v in enumerate(bits[1::2])]
>     expr = [p+v for p,(v,_) in zip(bits[::2],vv)]+bits[-1:]+[v for _,v 
> in vv]
>     return eval('(%s)' % ''.join(expr))

That's too ugly; here is a simpler version, same behav and caveats.

def cases(d) :
     import re
     d = repr(d)
     k,n = 1,1
     while n :
         d,n = re.subn('\\[(.*?)\\](.*)',
                       '_%s \\2 for _%s in (\\1,)' % (k,k),
                       d,1)
         k+=1
     return eval('('+d+')')

> 
> for t in cases({'a': {'x':[1,2,3], 'y':[4,5,6]},
>                    'b': {'x':[7,8,9], 'y':[10,11,12]}}) :
>     print t
> 
>     
> {'a': {'y': 4, 'x': 1}, 'b': {'y': 10, 'x': 7}}
> {'a': {'y': 4, 'x': 1}, 'b': {'y': 10, 'x': 8}}
> {'a': {'y': 4, 'x': 1}, 'b': {'y': 10, 'x': 9}}
> {'a': {'y': 4, 'x': 1}, 'b': {'y': 11, 'x': 7}}
> {'a': {'y': 4, 'x': 1}, 'b': {'y': 11, 'x': 8}}
> {'a': {'y': 4, 'x': 1}, 'b': {'y': 11, 'x': 9}}
> {'a': {'y': 4, 'x': 1}, 'b': {'y': 12, 'x': 7}}
> {'a': {'y': 4, 'x': 1}, 'b': {'y': 12, 'x': 8}}
> {'a': {'y': 4, 'x': 1}, 'b': {'y': 12, 'x': 9}}
> {'a': {'y': 4, 'x': 2}, 'b': {'y': 10, 'x': 7}}
> <snip/>
> 
> Caveats : (1) assert eval(repr(d))==d
>           (2) no square bracket in either keys or values



More information about the Python-list mailing list