python : How to make a combination according to the count of elements?

import random
import itertools

method_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
random.shuffle(method_list)

per = list(itertools.permutations(method_list, 4))

for ele in per:
    ss = set(list(ele))
    if len(ss) == 4:
        if not ('h' in ss and 'i' in ss):
            result.append(ss)

I want to make a total of 250 random combinations by taking 4 elements from my list.

like this:

{'c', 'b', 'd', 'a'}, {'c', 'e', 'b', 'a'}, {'c', 'b', 'f', 'a'}, {'c', 'b', 'g', 'a'}...
no name count
1 a 160
2 b 160
3 c 160
4 d 160
5 e 160
6 f 50
7 g 50
8 h 50
9 i 50
1000

But I don’t know how to make a combination that matches the number of elements according to the criteria in the table above.

The criteria are as follows.

  1. No duplicate alphabets in a combination.
  2. h and i are not in the same combination.
  3. total of 250 combinations while meeting the number of elements.

can anyone help me?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The other answers don’t try to meet the requirements in the table (only the exclusion of a joint occurrence of h and i), which I see as the main challenge of the question. My answer also doesn’t do that exactly, only approximately:

from random import choices

pop_1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
pop_2 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'i']
weights = [80, 80, 80, 80, 80, 25, 25, 50]

combos_1 = [choices(pop_1, weights=weights, k=4) for _ in range(125)]
combos_2 = [choices(pop_2, weights=weights, k=4) for _ in range(125)]
combos = combos_1 + combos_2

The random.choices() function chooses randomly (without replacement) from a population, and accepts a weights sequence (which serves as kind of a preference for the choosing). So, as I said, this doesn’t solve your problem exactly, only approximately (the larger the sample size, the smaller the relative error). The result looks like:

part        a    b    c    d    e    f    g    h    i    sum
--------  ---  ---  ---  ---  ---  ---  ---  ---  ---  -----
combos_1   74   85   71   92   88   20   21   49    0    500
combos_2   71   90   81   74   78   24   28    0   54    500
combos    145  175  152  166  166   44   49   49   54   1000

If you want to make sure that there are only unique combinations, then this would be better:

combos = set()
while len(combos) < 250:
    combos.add(tuple(choices(pop_1, weights=weights, k=4)))
    combos.add(tuple(choices(pop_2, weights=weights, k=4)))
if len(combos) == 251:
    combos.pop()

Method 2

Use this:

import random
result = list()
for _ in range(250):
    x = random.sample(method_list,4)
    if x.count('h')>0 and x.count('i')>0:
        pass
    else:
        result.append(x)
print(result)

Method 3

The random library could be avoided if using set properly, since returns always an unordered collection of terms. The counting part can be delegate to Counter from the collections library.

import collections as cl
import itertools as it

l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
exclude = set('hi')

combinations = []
combinations = list(set(c for c in it.permutations(l, 4) if not exclude <= set(c)))[:250]

counter = cl.Counter(l)
counter.update(it.chain(*combinations))

counter_ordered_by_key = sorted(counter.items(), key=lambda c: c[0])
print(counter_ordered_by_key)
# [('a', 120), ('b', 128), ('c', 114), ('d', 110), ('e', 121), ('f', 131), ('g', 121), ('h', 79), ('i', 85)]


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x