Wiem o itertools, ale wygląda na to, że może generować tylko permutacje bez powtórzeń.
Na przykład chciałbym wygenerować wszystkie możliwe rzuty kośćmi dla 2 kości. Więc potrzebuję wszystkich permutacji rozmiaru 2 z [1, 2, 3, 4, 5, 6], w tym powtórzeń: (1, 1), (1, 2), (2, 1) ... itd.
Jeśli to możliwe, nie chcę wdrażać tego od zera
python
permutation
combinatorics
Bwmat
źródło
źródło
random.randint
byłyby prostsze i wydajniejsze.Nie szukasz permutacji - chcesz produktu kartezjańskiego . W tym celu użyj produktu itertools:
from itertools import product for roll in product([1, 2, 3, 4, 5, 6], repeat = 2): print(roll)
źródło
W Pythonie 2.7 i 3.1 jest
itertools.combinations_with_replacement
funkcja:>>> list(itertools.combinations_with_replacement([1, 2, 3, 4, 5, 6], 2)) [(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (3, 3), (3, 4), (3, 5), (3, 6), (4, 4), (4, 5), (4, 6), (5, 5), (5, 6), (6, 6)]
źródło
(2, 1)
,(3, 2)
,(3, 1)
i podobne ... W ogóle to pomija wszystkie kombinacje, gdzie druga rolka jest niższy niż pierwszy.W takim przypadku rozumienie listy nie jest szczególnie potrzebne.
Dany
import itertools as it seq = range(1, 7) r = 2
Kod
list(it.product(seq, repeat=r))
Detale
Oczywiście iloczyn kartezjański może generować podzbiory permutacji. Wynika z tego jednak, że:
product
Permutacje z zamianą, n r
[x for x in it.product(seq, repeat=r)]
Permutacje bez zamiany, n!
[x for x in it.product(seq, repeat=r) if len(set(x)) == r]
# Equivalent list(it.permutations(seq, r))
W konsekwencji wszystkie funkcje kombinatoryczne mogą być implementowane z
product
:combinations_with_replacement
realizowane zproduct
combinations
zaimplementowane zpermutations
, które można zaimplementować za pomocąproduct
(patrz wyżej)źródło
Myślę, że znalazłem rozwiązanie używając tylko
lambdas
,map
ireduce
.product_function = lambda n: reduce(lambda x, y: x+y, map(lambda i: list(map(lambda j: (i, j), np.arange(n))), np.arange(n)), [])
Zasadniczo mapuję pierwszą funkcję lambda, która podając wiersz, iteruje kolumny
list(map(lambda j: (i, j), np.arange(n)))
to jest używane jako dane wyjściowe nowej funkcji lambda
lambda i:list(map(lambda j: (i, j), np.arange(n)))
który jest mapowany na wszystkie możliwe wiersze
map(lambda i: list(map(lambda j: (i, j), np.arange(n))), np.arange(m))
a następnie redukujemy wszystkie otrzymane listy do jednej.
nawet lepiej
Można również użyć dwóch różnych liczb.
prod= lambda n, m: reduce(lambda x, y: x+y, map(lambda i: list(map(lambda j: (i, j), np.arange(m))), np.arange(n)), [])
źródło
Najpierw będziesz chciał zamienić generator zwracany przez itertools.permutations (list) na listę. Następnie możesz użyć set (), aby usunąć duplikaty. Coś jak poniżej:
def permutate(a_list): import itertools return set(list(itertools.permutations(a_list)))
źródło