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