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

Time:05-01

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?

CodePudding user response:

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)

CodePudding user response:

The other answer doesn't try to meet the requirements in the table (apart from the exclusion of a joint occurrence of h and i). 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()

CodePudding user response:

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)]

  • Related