asl
asl

Reputation: 481

Returning all possible combinations of a python dictionary in a comprehensive way

I want to return all possible key combinations of a python dictionary. In my case, it is a two-levels hierarchy dictionary.

My first attempt seems like a pseudo-code-like sequence of for loops. It works but it is ugly and it gets really painful if I have a lot of data.

I want a do the same task with the dict-comprehension approach.

Here is my attempt. Using this technique, I could easily end up with many - way too many - for loops.

dic = {
    'Sex' : {'Man' : 0, 'Woman' : 1}, 
    'Age group' : {'0-14yrs' : 0, '15-25yrs' : 1, '26-35yrs' : 2}
}

for x in range(len(list(dic['Sex'].keys()))):
    for y in range(len(list(dic['Age group'].keys()))):
        sex = list(dic['Sex'].keys())[x]
        age = list(dic['Age group'].keys())[y]
        print(sex,age)


Man 0-14yrs
Man 15-25yrs
Man 26-35yrs
Woman 0-14yrs
Woman 15-25yrs
Woman 26-35yrs

Upvotes: 3

Views: 242

Answers (2)

chepner
chepner

Reputation: 531075

I would use itertools.product.

for sex, age in itertools.product(dic['Sex'], dic['Age group']):
    print(sex, age)

product returns an generator of tuples, which you can do with what you like.

For an arbitrary dict, where you don't necessarily know the keys or their ordering in advance, I would tag each value with its key first.

>>> for t in list(itertools.product(*[[(k, v) for v in dic[k] ] for k in dic])):
...   print(t)
...
(('Age group', '15-25yrs'), ('Sex', 'Woman'))
(('Age group', '15-25yrs'), ('Sex', 'Man'))
(('Age group', '0-14yrs'), ('Sex', 'Woman'))
(('Age group', '0-14yrs'), ('Sex', 'Man'))
(('Age group', '26-35yrs'), ('Sex', 'Woman'))
(('Age group', '26-35yrs'), ('Sex', 'Man'))

Now you at least know the "type" of each value in the corresponding tuple; it doesn't depend on any specific ordering involving the original dict.

Upvotes: 3

Noam Peled
Noam Peled

Reputation: 4622

If you want your solution to be general as possible, you can do something like that:

from itertools import product
product(*dic.values())

That will give you a generator with the following values:

[('Man', '0-14yrs'), ('Man', '15-25yrs'), ('Man', '26-35yrs'), ('Woman', '0-14yrs'), ('Woman', '15-25yrs'), ('Woman', '26-35yrs')]

Upvotes: 1

Related Questions