# Simpler way to get combinations and group them based on key values?

142
6
01-30-2023 01:53 PM
by
Regular Contributor

Hi,

I wanted to see if anyone could help with figuring out if there is a simpler way to code what I have below. What I have below works fine but I wanted to see if there was a simpler way to write the code.

``````Fields, Grps = ['FieldA','FieldB','FieldC'], ['GroupA','GroupB','GroupC']
Main = [['DOG','CAT','HORSE'], ['HOUSE','BARN'], ['FIELDS', 'YARD'],['MOUSE','SNAKE','LIZARD','OTHER'],['AQUARIUM','GLASS TANK','SMALL CAGE'],
['HOUSE','APARTMENT','PET STORE'],['COW','PIG', 'SHEEP'], ['FIELDS','PASTURES'], ['BARN','FARM HOUSE','OTHER']]
MainDict = dict(zip([chr(i) for i in range(ord('A'),ord('A')+len(Main))], Main))
EstVOrder = [[i for i in [chr(i) for i in range(ord('A')+n,ord('A')+n+len(Fields))]] for n in range(0,len(Main),len(Main)//len(Fields))]
Main = dict(zip(Grps,[[[x,y,z] for x in MainDict[a] for y in MainDict[b] for z in MainDict[c]] for a,b,c in EstVOrder]))
print (Main)``````

I would also like to know if the code above is properly written.

Tags (8)
1 Solution

Accepted Solutions
MVP Esteemed Contributor

After taking a longer look at your data and code, it seems you are trying to reinvent the product - itertools — Functions creating iterators for efficient looping wheel.  I can confidently state that any native Python code someone writes will not outperform the compiled functions in the itertools module.

``````from itertools import product
Fields, Grps = ['FieldA','FieldB','FieldC'], ['GroupA','GroupB','GroupC']
Main = [['DOG','CAT','HORSE'], ['HOUSE','BARN'], ['FIELDS', 'YARD'],['MOUSE','SNAKE','LIZARD','OTHER'],['AQUARIUM','GLASS TANK','SMALL CAGE'],
['HOUSE','APARTMENT','PET STORE'],['COW','PIG', 'SHEEP'], ['FIELDS','PASTURES'], ['BARN','FARM HOUSE','OTHER']]
Main = {g:list(product(*Main[i*3:i*3+3])) for i,g in enumerate(Grps)}
print(Main)``````

6 Replies
by
MVP Regular Contributor

We code for people, so keep it zen:

``import this``

...

Beautiful is better than ugly.

Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Special cases aren't special enough to break the rules.
Although practicality beats purity.

...

If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.

``````# MainDict = {'A': ['DOG', 'CAT', 'HORSE'], 'B': ['HOUSE', 'BARN'], ...}

# Main = {'GroupA': [['DOG', 'HOUSE', 'FIELDS'], ..., ['HORSE', 'BARN', 'YARD']], ...}``````

I suspect Pandas would make short work of creating your final dictionary in a much more elegant way.

by
Regular Contributor

Thanks @JeffK,

The code itself was to see if there was a way to create a list of lists with combinations of values that were the same length and order as the fields. I was also trying to do it with the fewest lines of code possible to see if it could be done. I know the code itself is not that pretty, beautiful, or easy to read/understand, but my goal was to see if I could achieve a complex task with the fewest lines of code.

MVP Esteemed Contributor

Code golf might be a fun exercise, but it usually leads to challenging code to read and even poorer performing code at times.

by
Regular Contributor

Thanks @JoshuaBixby,

I thought of it as a fun exercise to see if I could utilize it for smaller scripts since it gave me the opportunity to try and test what I can do. I was not aware of the performance issues regarding how the code is written, so I will have a to run a few test scripts to see how significant the difference is.

MVP Esteemed Contributor

After taking a longer look at your data and code, it seems you are trying to reinvent the product - itertools — Functions creating iterators for efficient looping wheel.  I can confidently state that any native Python code someone writes will not outperform the compiled functions in the itertools module.

``````from itertools import product
Fields, Grps = ['FieldA','FieldB','FieldC'], ['GroupA','GroupB','GroupC']
Main = [['DOG','CAT','HORSE'], ['HOUSE','BARN'], ['FIELDS', 'YARD'],['MOUSE','SNAKE','LIZARD','OTHER'],['AQUARIUM','GLASS TANK','SMALL CAGE'],
['HOUSE','APARTMENT','PET STORE'],['COW','PIG', 'SHEEP'], ['FIELDS','PASTURES'], ['BARN','FARM HOUSE','OTHER']]
Main = {g:list(product(*Main[i*3:i*3+3])) for i,g in enumerate(Grps)}
print(Main)``````

by
Regular Contributor

Thanks @JoshuaBixby

I didn't even realize that I had replicated an existing function. I knew of the itertools, but from examples I have seen online, I thought it might be limited, or there were other ways to achieve the same thing without importing another module. I will research more into these and other python modules to see if some of the code that I have written can be simplified using an existing module.