Combinations From Dictionary With List Values Using Python
Solution 1:
import itertools as it
varNames = sorted(variants)
combinations = [dict(zip(varNames, prod)) for prod in it.product(*(variants[varName] for varName in varNames))]
Hm, this returns:
[{'debug': 'on', 'locale': 'de_DE'},
{'debug': 'on', 'locale': 'en_US'},
{'debug': 'on', 'locale': 'fr_FR'},
{'debug': 'off', 'locale': 'de_DE'},
{'debug': 'off', 'locale': 'en_US'},
{'debug': 'off', 'locale': 'fr_FR'}]
which is probably not exactly, what you want. Let me adapt it...
combinations = [ [ {varName: val} forvarName, val inzip(varNames, prod) ] forprodin it.product(*(variants[varName] forvarNamein varNames))]
returns now:
[[{'debug': 'on'}, {'locale': 'de_DE'}],
[{'debug': 'on'}, {'locale': 'en_US'}],
[{'debug': 'on'}, {'locale': 'fr_FR'}],
[{'debug': 'off'}, {'locale': 'de_DE'}],
[{'debug': 'off'}, {'locale': 'en_US'}],
[{'debug': 'off'}, {'locale': 'fr_FR'}]]
Voilà ;-)
Solution 2:
combinations = [[{key: value} for (key, value) in zip(variants, values)]
forvalues in itertools.product(*variants.values())]
[[{'debug': 'on'}, {'locale': 'de_DE'}],
[{'debug': 'on'}, {'locale': 'en_US'}],
[{'debug': 'on'}, {'locale': 'fr_FR'}],
[{'debug': 'off'}, {'locale': 'de_DE'}],
[{'debug': 'off'}, {'locale': 'en_US'}],
[{'debug': 'off'}, {'locale': 'fr_FR'}]]
Solution 3:
This is what I use:
from itertools import product
defdictproduct(dct):
for t in product(*dct.itervalues()):
yielddict(zip(dct.iterkeys(), t))
which applied to your example gives:
>>> list(dictproduct({"debug":["on", "off"], "locale":["de_DE", "en_US", "fr_FR"]}))
[{'debug': 'on', 'locale': 'de_DE'},
{'debug': 'on', 'locale': 'en_US'},
{'debug': 'on', 'locale': 'fr_FR'},
{'debug': 'off', 'locale': 'de_DE'},
{'debug': 'off', 'locale': 'en_US'},
{'debug': 'off', 'locale': 'fr_FR'}]
I find this is more readable than the one liners above.
Also, it returns an iterator like itertools.product
so it leaves it up to the user whether to instantiate a list or just consume the values one at a time.
Solution 4:
I assume you want the cartesian product of all the keys? So if you had another entry, "foo", with values [1, 2, 3], then you'd have 18 total entries?
First, put the values in a list, where each entry is one of the possible variants in that spot. In your case, we want:
[[{'debug': 'on'}, {'debug': 'off'}], [{'locale': 'de_DE'}, {'locale': 'en_US'}, {'locale': 'fr_FR'}]]
To do that:
>>> stuff = []
>>> for k,v in variants.items():
blah = []
for i in v:
blah.append({k:i})
stuff.append(blah)
>>> stuff
[[{'debug': 'on'}, {'debug': 'off'}], [{'locale': 'de_DE'}, {'locale': 'en_US'}, {'locale': 'fr_FR'}]]
Next we can use a Cartesian product function to expand it...
>>> defcartesian_product(lists, previous_elements = []):
iflen(lists) == 1:
for elem in lists[0]:
yield previous_elements + [elem, ]
else:
for elem in lists[0]:
for x in cartesian_product(lists[1:], previous_elements + [elem, ]):
yield x
>>> list(cartesian_product(stuff))
[[{'debug': 'on'}, {'locale': 'de_DE'}], [{'debug': 'on'}, {'locale': 'en_US'}], [{'debug': 'on'}, {'locale': 'fr_FR'}], [{'debug': 'off'}, {'locale': 'de_DE'}], [{'debug': 'off'}, {'locale': 'en_US'}], [{'debug': 'off'}, {'locale': 'fr_FR'}]]
Note that this doesn't copy the dicts, so all the {'debug': 'on'}
dicts are the same.
Post a Comment for "Combinations From Dictionary With List Values Using Python"