Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

To generate a list, allowing duplicates and fitting a condition

From choices [1,2,3], I want to output all possible combinations, allowing duplicates in the choices, in a list of 5 elements.

In each of the lists, there must be at least one of 1, at least one of 2, and at least one of 3.

A clumsy way as below. It firstly generates a list of 5 using either in [1,2,3]. All generated lists are examined to have at least each of [1,2,3]. The qualified ones are put into a big list. Then the duplicates in the big list are removed (loop it many times to make sure good coverage):

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import random
import itertools

choices = [1,2,3]

big_list = []

for a in range(10000):
    new_list = [random.choice(choices) for i in range(5)]

    if new_list.count(1) >= 1 and new_list.count(2) >= 1 and new_list.count(3) >= 1:
        big_list.append(new_list)

big_list.sort()

final_list = list(big_list for big_list, _ in itertools.groupby(big_list))
# this line to remove the duplicates in the list of lists

print (final_list)

Considering the sequence matters, that is, [1,1,1,2,3] and [2,3,1,1,1] are two different lists.

What would be the smarter and more comprehensive way to do so? Thank you.

>Solution :

Maybe you could could use itertools.combinations_with_replacement, itertools.permutations along with collections.Counter:

>>> from collections import Counter
>>> from itertools import combinations_with_replacement, permutations
>>> 
>>> def is_valid_combination(comb: tuple) -> bool:
...     digit_counts = Counter(comb)
...     return digit_counts[1] >= 1 and \
...            digit_counts[2] >= 1 and \
...            digit_counts[3] >= 1
... 
>>> choices = [1, 2, 3]
>>> valid_combinations = [
...     c for c in combinations_with_replacement(choices, r=5)
...     if is_valid_combination(c)
... ]
>>> 
>>> valid_combinations
[(1, 1, 1, 2, 3), (1, 1, 2, 2, 3), (1, 1, 2, 3, 3), (1, 2, 2, 2, 3), (1, 2, 2, 3, 3), (1, 2, 3, 3, 3)]
>>>
>>> all_permutations_of_valid_combinations = {
...     p
...     for c in valid_combinations for p in permutations(c)
... }
>>>
>>> all_permutations_of_valid_combinations
{(2, 1, 3, 1, 2), (2, 1, 3, 2, 1), (3, 3, 2, 1, 3), (1, 2, 3, 2, 3), (1, 2, 1, 3, 1), (3, 1, 2, 3, 2), (3, 3, 3, 2, 1), (3, 2, 2, 1, 1), (1, 2, 2, 3, 1), (1, 3, 2, 2, 3), (1, 3, 2, 3, 2), (1, 2, 1, 1, 3), (3, 1, 3, 3, 2), (3, 1, 1, 2, 3), (2, 1, 3, 2, 3), (1, 2, 2, 1, 3), (1, 2, 1, 3, 3), (2, 3, 3, 1, 2), (2, 3, 3, 2, 1), (3, 3, 1, 2, 1), (3, 2, 3, 2, 1), (1, 2, 2, 3, 3), (3, 2, 1, 1, 1), (2, 2, 1, 3, 1), (2, 3, 1, 1, 1), (1, 3, 1, 2, 3), (3, 3, 1, 1, 2), (3, 2, 3, 1, 2), (2, 1, 2, 3, 1), (2, 2, 1, 1, 3), (3, 2, 1, 3, 1), (2, 3, 1, 3, 1), (1, 1, 3, 2, 1), (2, 3, 2, 1, 2), (2, 3, 2, 2, 1), (2, 1, 2, 1, 3), (3, 2, 1, 1, 3), (2, 2, 1, 3, 3), (2, 3, 1, 1, 3), (2, 3, 1, 2, 2), (3, 2, 3, 3, 1), (1, 1, 3, 1, 2), (2, 1, 2, 3, 3), (3, 3, 2, 2, 1), (3, 1, 2, 1, 2), (3, 2, 1, 3, 3), (3, 1, 2, 2, 1), (2, 3, 1, 3, 3), (1, 1, 3, 2, 3), (3, 3, 3, 1, 2), (1, 2, 3, 1, 1), (1, 1, 3, 3, 2), (3, 1, 3, 1, 2), (2, 3, 2, 3, 1), (1, 3, 2, 1, 1), (2, 1, 3, 3, 1), (3, 2, 2, 3, 1), (3, 1, 2, 2, 3), (1, 3, 2, 2, 2), (1, 2, 3, 1, 3), (1, 3, 2, 3, 1), (3, 2, 2, 1, 3), (2, 2, 3, 2, 1), (3, 1, 1, 2, 2), (1, 1, 2, 2, 3), (2, 1, 3, 2, 2), (1, 3, 3, 2, 2), (3, 3, 1, 3, 2), (2, 1, 1, 3, 1), (1, 3, 2, 1, 3), (2, 1, 3, 3, 3), (3, 1, 3, 2, 2), (2, 2, 3, 1, 2), (1, 1, 2, 3, 1), (3, 2, 1, 2, 2), (1, 2, 2, 3, 2), (3, 3, 1, 2, 3), (1, 3, 2, 3, 3), (1, 2, 1, 2, 3), (3, 2, 3, 1, 1), (1, 3, 1, 2, 2), (1, 2, 2, 2, 3), (2, 1, 1, 3, 3), (3, 1, 1, 3, 2), (1, 1, 2, 3, 3), (1, 3, 3, 3, 2), (2, 3, 2, 1, 1), (2, 2, 1, 2, 3), (2, 2, 1, 3, 2), (1, 2, 3, 3, 1), (3, 2, 3, 1, 3), (2, 3, 1, 2, 1), (2, 1, 3, 1, 1), (3, 3, 2, 1, 2), (1, 2, 3, 2, 2), (1, 3, 1, 3, 2), (3, 1, 2, 3, 1), (2, 2, 2, 3, 1), (2, 1, 2, 2, 3), (1, 2, 3, 3, 3), (2, 3, 1, 2, 3), (2, 1, 3, 1, 3), (3, 2, 2, 2, 1), (1, 2, 1, 3, 2), (2, 3, 3, 1, 1), (3, 1, 2, 3, 3), (3, 2, 2, 1, 2), (3, 1, 1, 2, 1), (1, 3, 3, 2, 1), (2, 3, 3, 3, 1), (2, 1, 1, 1, 3), (1, 3, 2, 1, 2), (2, 1, 3, 3, 2), (1, 1, 1, 2, 3), (3, 1, 3, 2, 1), (1, 1, 1, 3, 2), (2, 2, 3, 1, 1), (3, 1, 1, 1, 2), (1, 1, 2, 1, 3), (1, 3, 3, 1, 2), (3, 2, 1, 2, 1), (2, 3, 3, 1, 3), (3, 3, 1, 2, 2), (2, 2, 3, 3, 1), (1, 3, 1, 2, 1), (1, 3, 3, 2, 3), (3, 2, 1, 1, 2), (2, 1, 1, 3, 2), (2, 3, 1, 1, 2), (3, 1, 3, 2, 3), (2, 2, 3, 1, 3), (1, 3, 1, 1, 2), (1, 1, 2, 3, 2), (2, 1, 2, 3, 2), (3, 2, 1, 2, 3), (3, 1, 2, 1, 1), (3, 2, 1, 3, 2), (2, 1, 1, 2, 3), (2, 3, 1, 3, 2), (1, 1, 3, 2, 2), (2, 3, 2, 1, 3), (3, 3, 2, 3, 1), (3, 3, 2, 1, 1), (1, 2, 3, 2, 1), (3, 1, 2, 1, 3), (2, 2, 2, 1, 3), (3, 1, 2, 2, 2), (1, 3, 2, 2, 1), (1, 2, 3, 1, 2), (1, 2, 3, 3, 2)}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading