python : 如何根据元素个数进行组合?

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)

我想通过从我的列表中取出 4 个元素来进行总共 250 种随机组合。

像这样:

{'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

但是我不知道如何根据上面table中的条件来匹配元素数量的组合。

评判标准如下

  1. 组合中没有重复的字母。
  2. hi不是同一个组合。
  3. 总共250种组合,同时满足元素数量。

谁能帮帮我?

使用这个:

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)

其他答案不要试图满足table中的要求(仅排除hi),我认为这是问题的主要挑战。我的回答也没有完全,只是大约:

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

random.choices() 函数从总体中随机选择(无替换),并接受 weights 序列(作为选择的一种偏好)。因此,正如我所说,这并不能完全解决您的问题,只能近似解决(样本量越大,相对误差越小)。结果如下:

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

如果你想确保只有唯一个组合,那么这样会更好:

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

如果正确使用 set,可以避免使用 random 库,因为 returns 总是无序的术语集合。计数部分可以从 collections 库委托给 Counter

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