Reputation: 497
I have a nested dictionary in Python like this:
funcs = {1:{-1:{'a': 1, 'b': 2}, 0:{'a': 3, 'b': 4}, 1:{'a': 5, 'b': 6}},
2:{-2:{'a': 7, 'b': 8}, -1:{'a': 9, 'b': 10}, 0:{'a': 11, 'b': 12}, 1:{'a': 13, 'b': 14}, 2:{'a': 15, 'b': 16}}}
It has three levels of nested dictionaries:
m
keys run from 1
to some N
(here N = 2
)n
keys run from -m
to m
: for m=1
, it is -1, 0, 1
, for m=2
, it is -2,-1,0,1,2
p
keys run over 'a'
and 'b'
1, 2, 3, ..., 16
are just sample values.I need to run a function g(x,y)
over each possible pair of values in the lowest level of the dictionary (so 16x16 operations). Obviously, I can do this by running over all keys in a 6-nested loop, but I was hoping for something more efficient and pythonic.
If the outermost level had only m=1, the resulting matrix would look like:
g(f[1][-1][a], f[1][-1][a]), g(f[1][-1][a], f[1][-1][b]), g(f[1][-1][a], f[1][0][a]), g(f[1][-1][a], f[1][0][b]), g(f[1][-1][a], f[1][1][a]), g(f[1][-1][a], f[1][1][b])
g(f[1][-1][b], f[1][-1][a]), g(f[1][-1][b], f[1][-1][b]), g(f[1][-1][b], f[1][0][a]), g(f[1][-1][b], f[1][0][b]), g(f[1][-1][b], f[1][1][a]), g(f[1][-1][b], f[1][1][b])
g(f[1][0][a], f[1][-1][a]), g(f[1][0][a], f[1][-1][b]), g(f[1][0][a], f[1][0][a]), g(f[1][0][a], f[1][0][b]), g(f[1][0][a], f[1][1][a]), g(f[1][0][a], f[1][1][b])
g(f[1][0][b], f[1][-1][a]), g(f[1][0][b], f[1][-1][b]), g(f[1][0][b], f[1][0][a]), g(f[1][0][b], f[1][0][b]), g(f[1][0][b], f[1][1][a]), g(f[1][0][b], f[1][1][b])
g(f[1][1][a], f[1][-1][a]), g(f[1][1][a], f[1][-1][b]), g(f[1][1][a], f[1][0][a]), g(f[1][1][a], f[1][0][b]), g(f[1][1][a], f[1][1][a]), g(f[1][1][a], f[1][1][b])
g(f[1][1][b], f[1][-1][a]), g(f[1][1][b], f[1][-1][b]), g(f[1][1][b], f[1][0][a]), g(f[1][1][b], f[1][0][b]), g(f[1][1][b], f[1][1][a]), g(f[1][1][b], f[1][1][b])
Upvotes: 0
Views: 162
Reputation: 3519
itertools.product
.itertools.product
generate permutation of numbers.import itertools
funcs = {1:{-1:{'a': 1, 'b': 2}, 0:{'a': 3, 'b': 4}, 1:{'a': 5, 'b': 6}},
2:{-2:{'a': 7, 'b': 8}, -1:{'a': 9, 'b': 10}, 0:{'a': 11, 'b': 12}, 1:{'a': 13, 'b': 14}, 2:{'a': 15, 'b': 16}}}
l = []
for k,v in funcs.items():
for k1, v1 in v.items():
l.extend(v1.values())
print(l)
combi = list(itertools.product(l, repeat=2))
# call fucn of each of combi
for val in combi:
# print(foo(combi))
pass
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
Upvotes: 1
Reputation: 6132
IIUC, for example if you want to sum the a,b
pairs of values and put them on a list:
funcs = {1:{-1:{'a': 1, 'b': 2}, 0:{'a': 3, 'b': 4}, 1:{'a': 5, 'b': 6}},
2:{-2:{'a': 7, 'b': 8}, -1:{'a': 9, 'b': 10}, 0:{'a': 11, 'b': 12},
1:{'a': 13, 'b': 14}, 2:{'a': 15, 'b': 16}}}
def g(funcs):
return [sum(v2.values()) for v in funcs.values() for v2 in v.values()]
[3, 7, 11, 15, 19, 23, 27, 31]
Please tell me if you need a more specific application that's not easily generalizable from this.
Upvotes: 0