This is a new section dedicated to small snippets (well, just one so far) of code I've written that I am particularly fond of...
Recurion & Generators
This is the description of the problem.
Given a data struct like this:
x = {
'lion':['a','b'],
'tiger':['m','o'],
'cheetah':['y','z'],
}
I want to end up with this:
y = [
{ 'lion':'a', 'tiger':'m', 'cheetah':'y', },
{ 'lion':'a', 'tiger':'m', 'cheetah':'z', },
{ 'lion':'a', 'tiger':'o', 'cheetah':'y', },
{ 'lion':'a', 'tiger':'o', 'cheetah':'z', },
{ 'lion':'b', 'tiger':'m', 'cheetah':'y', },
{ 'lion':'b', 'tiger':'m', 'cheetah':'z', },
{ 'lion':'b', 'tiger':'o', 'cheetah':'y', },
{ 'lion':'b', 'tiger':'o', 'cheetah':'z', },
]
And here is what I came up with. I really like how generators and recursion play well together. Makes for an elegant solution IMO.
def combinator(items):
expanded = [[(key,v) for v in values] for key,values in items]
return (dict(l) for l in _citer(expanded))
def _citer(lst):
head,tail = lst[0],lst[1:]
if not tail:
for t in head:
yield [t]
else:
for t in head:
for h in _citer(tail):
yield [t] + h
if __name__=="__main__":
from pprint import pprint
val = combinator(x.items())
pprint(val)