programing

목록에서 "반복/교체가 있는 순열"을 가져오려면 어떻게 해야 합니까?(목록 자체가 있는 데카르트 제품)

javajsp 2023. 11. 5. 11:00

목록에서 "반복/교체가 있는 순열"을 가져오려면 어떻게 해야 합니까?(목록 자체가 있는 데카르트 제품)

내가 목록을 가지고 있다고 가정해 보겠습니다.die_faces = [1, 2, 3, 4, 5, 6]. 주사위 두 개를 굴릴 때 가능한 36가지 결과를 모두 생성하고자 합니다.(1, 1),(1, 2),(2, 1)등. 사용해보면.permutations로부터itertools표준 라이브러리:

>>> import itertools
>>> die_faces = [1, 2, 3, 4, 5, 6]
>>> list(itertools.permutations(die_faces, 2))
[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 1), (2, 3), (2, 4), (2, 5), (2, 6), (3, 1), (3, 2), (3, 4), (3, 5), (3, 6), (4, 1), (4, 2), (4, 3), (4, 5), (4, 6), (5, 1), (5, 2), (5, 3), (5, 4), (5, 6), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5)]

30개의 결과만 있고, 두 주사위에 같은 숫자가 나오는 결과는 없습니다.반복하지 않고 순열만 생성하는 것 같습니다.이거 어떻게 고쳐요?

데카르트 제품을 찾고 있습니다.

수학에서 데카르트 곱(Cartesian product)은 두 집합의 직접적인 곱입니다.

당신의 경우, 이것은{1, 2, 3, 4, 5, 6} x {1, 2, 3, 4, 5, 6}. itertools도움이 될 수 있습니다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)

순열을 원하는 것이 아니라 데카르트 제품을 원하는 것입니다.이터툴의 제품을 사용하는 경우:

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

python 2.7과 3.1에는 다음과 같은 기능이 있습니다.

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

세부 사항

분명 데카르트 곱은 부분 순열 집합을 생성할 수 있습니다.그러나 다음과 같습니다.

  • 교체와 함께: 다음을 통해 모든 순열을r 생성합니다.product
  • 교체 없이: 후자에서 필터

치환이r 있는 순열, n

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

기본적으로 행이 주어진 첫 번째 람다 함수를 매핑하고 있습니다. 열 ns를 반복합니다.

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(목록)에서 반환되는 생성기를 목록으로 먼저 전환합니다.그런 다음 두 번째로 set()을 사용하여 중복을 제거할 수 있습니다. 아래와 같은 것:

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

언급URL : https://stackoverflow.com/questions/3099987/how-can-i-get-permutations-with-repetitions-replacement-from-a-list-cartesian