В этом случае вам лучше использовать комбинированные функции.
Кажется, что DiscreteUniform не для изменения элементов после создания.
from sympy.functions.combinatorial.numbers import nC, nP
print(1 / nP(3, 2)) # 1/6
Если вы не заботитесь о заказе,
print(nP(2, 2) / nP(3, 2)) # 1/3
Под ред. (а также модифицировано для python3)
Для N из M вещей вы можете просто сделать, как показано ниже
from sympy.functions.combinatorial.numbers import nC, nP
def pickProb(candidates, picks, ordered=False):
picks_num = len(picks)
numerator = nP(picks_num, picks_num) if ordered else 1
denominator = nP(len(candidates), picks_num)
return numerator / denominator
print(pickProb('RWB', 'RW')) # 1/6
print(pickProb('RWBrwba', 'Ra')) # 1/42
print(pickProb('RWBrwba', 'RWa')) # 1/210
print(pickProb('RWBrwba', 'RWa', ordered=True)) # 1/35
И комбинированные функции могут также обрабатывать дубликаты, такие как 'R', 'R', 'W', 'B'.
from operator import mul
from sympy.functions.combinatorial.numbers import nC, nP
def pickProb(candidates, picks):
picks_num = len(picks)
c_counts = {}
for c in candidates:
c_counts[c] = c_counts[c] + 1 if c in c_counts else 1
p_counts = {}
for p in picks:
p_counts[p] = p_counts[p] + 1 if p in p_counts else 1
combinations = reduce(mul, [nP(c_counts[x], p_counts[x]) for x in p_counts.keys()], 1)
denominator = nP(len(candidates), picks_num) / combinations
return 1 / denominator
print(pickProb('RWBra', 'RWa')) # 1/60
print(pickProb('RRRWa', 'RWa')) # 1/20
print(pickProb('RRRWa', 'RRa')) # 1/10
Но DiscreteUniform
не может, потому что этот случай не "однороден".
from sympy.stats import DiscreteUniform, density, P, Hypergeometric
from sympy import Symbol, Eq
deck = DiscreteUniform('M', 'RRWB')
print(density(deck).dict) # {W: 1/4, R: 1/4, B: 1/4}
print(P(Eq(deck, Symbol('R')))) # 1/4