[python] 반복으로 순열 생성

itertools에 대해 알고 있지만 반복없이 순열 만 생성 할 수있는 것 같습니다.

예를 들어, 2 개의 주사위에 대해 가능한 모든 주사위 굴림을 생성하고 싶습니다. 따라서 반복을 포함하여 [1, 2, 3, 4, 5, 6] 크기 2의 모든 순열이 필요합니다 : (1, 1), (1, 2), (2, 1) … 등

가능하다면 처음부터 구현하고 싶지 않습니다.



답변

Cartesian Product를 찾고 있습니다.

수학에서 데카르트 곱 (또는 제품 세트)은 두 세트의 직접 곱입니다.

귀하의 경우 이것은 {1, 2, 3, 4, 5, 6}x {1, 2, 3, 4, 5, 6}입니다.
itertools거기에서 당신을 도울 수 있습니다 :

import itertools
x = [1, 2, 3, 4, 5, 6]
[p for p in itertools.product(x, repeat=2)]
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 1), (2, 2), (2, 3),
 (2, 4), (2, 5), (2, 6), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6),
 (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (5, 1), (5, 2), (5, 3),
 (5, 4), (5, 5), (5, 6), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6)]

무작위 주사위 굴림을 얻으려면 ( 완전히 비효율적 인 방식으로 ) :

import random
random.choice([p for p in itertools.product(x, repeat=2)])
(6, 3)


답변

순열을 찾는 것이 아니라 Cartesian Product 를 원합니다 . 이 사용 제품 의 경우 itertools :

from itertools import product
for roll in product([1, 2, 3, 4, 5, 6], repeat = 2):
    print(roll)


답변

파이썬 2.7과 3.1에는 itertools.combinations_with_replacement함수가 있습니다 :

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


답변

이 경우 목록 이해력은 특별히 필요하지 않습니다.

주어진

import itertools as it


seq = range(1, 7)
r = 2

암호

list(it.product(seq, repeat=r))

세부

당연히 데카르트 곱은 순열의 하위 집합을 생성 할 수 있습니다. 그러나 다음과 같습니다.

  • 여분으로 모든 순열 생성 N R 비아product
  • 교체없이 : 후자에서 필터

치환이있는 순열, n r

[x for x in it.product(seq, repeat=r)]

대체없는 순열, n!

[x for x in it.product(seq, repeat=r) if len(set(x)) == r]
# Equivalent
list(it.permutations(seq, r))

결과적으로 모든 조합 함수는 다음에서 구현할 수 있습니다 product.


답변

lambdas, map및을 사용하여 해결책을 찾은 것 같습니다 reduce.

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

기본적으로 행을 제공하고 열을 반복하는 첫 번째 람다 함수를 매핑하고 있습니다.

list(map(lambda j: (i, j), np.arange(n)))

그러면 이것은 새로운 람다 함수의 출력으로 사용됩니다.

lambda i:list(map(lambda j: (i, j), np.arange(n)))

가능한 모든 행에 매핑됩니다.

map(lambda i: list(map(lambda j: (i, j), np.arange(n))), np.arange(m))

그런 다음 모든 결과 목록을 하나로 줄입니다.

훨씬 더

두 개의 다른 숫자를 사용할 수도 있습니다.

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


답변

먼저 itertools.permutations (list)에서 반환 한 생성기를 목록으로 먼저 전환해야합니다. 그런 다음 두 번째로 set ()를 사용하여 중복을 제거 할 수 있습니다.

def permutate(a_list):
    import itertools
    return set(list(itertools.permutations(a_list)))


답변