source

길이가 같지 않은 두 리스트 간의 순열

lovecheck 2022. 10. 20. 21:59
반응형

길이가 같지 않은 두 리스트 간의 순열

구현하려는 알고리즘에 대한 이해가 잘 안 돼요.2개의 리스트가 있는데, 그 2개의 리스트에서 특정 조합을 선택하려고 합니다.

여기 예가 있습니다.

names = ['a', 'b']
numbers = [1, 2]

이 경우의 출력은 다음과 같습니다.

[('a', 1), ('b', 2)]
[('b', 1), ('a', 2)]

나는, 즉 난 숫자보다 이름이 더 많을지도 몰라 숫자보다는 좀 더 이름이 표시될 수 있다.len(names) >= len(numbers)예를 들어 보자. 3이름과 2를 번호: 있다.다음은 3개의 이름과 2개의 번호로이루어진 예입니다.

names = ['a', 'b', 'c']
numbers = [1, 2]

출력:

[('a', 1), ('b', 2)]
[('b', 1), ('a', 2)]
[('a', 1), ('c', 2)]
[('c', 1), ('a', 2)]
[('b', 1), ('c', 2)]
[('c', 1), ('b', 2)]

가장 간단한 방법가장 간단한 방법은을 사용하는 것입니다.itertools.product::

a = ["foo", "melon"]
b = [True, False]
c = list(itertools.product(a, b))
>> [("foo", True), ("foo", False), ("melon", True), ("melon", False)]

위의 가장 단순한 것보다 단순할 수 있습니다.

>>> a = ["foo", "bar"]
>>> b = [1, 2, 3]
>>> [(x,y) for x in a for y in b]  # for a list
[('foo', 1), ('foo', 2), ('foo', 3), ('bar', 1), ('bar', 2), ('bar', 3)]
>>> ((x,y) for x in a for y in b)  # for a generator if you worry about memory or time complexity.
<generator object <genexpr> at 0x1048de850>

아무 의미도 없이

주의: 이 답변은 위의 질문에 대한 답변입니다.구글에서 온 고객님이 파이썬에서 데카르트 제품을 구할 방법을 찾고 계신다면,itertools.product아니면 간단한 목록 이해 위한 다른 대답은 보려면 기대할 수 있다.또는 간단한 목록 이해가 여러분이 찾고 있는 것일 수 있습니다.다른 답을 참조하십시오.


예를 들어 가정하다len(list1) >= len(list2). 그리고 여러분이 필요할 보이는 것과 길이 그러면 당신이 원하는 것은 길이의 모든 배열을 취하는 것입니다의 모든 순열을 취할 예정이다.len(list2)부터에서list1그리고 list2에서 항목과 그것들을 조화시키다.목록2의 항목과 일치시킵니다.이무기에서:이무기:

import itertools
list1=['a','b','c']
list2=[1,2]

[list(zip(x,list2)) for x in itertools.permutations(list1,len(list2))]

돌아온다

[[('a', 1), ('b', 2)], [('a', 1), ('c', 2)], [('b', 1), ('a', 2)], [('b', 1), ('c', 2)], [('c', 1), ('a', 2)], [('c', 1), ('b', 2)]]

이 함수로 제공되는 고유 조합만 있는 리스트를 찾고 있었습니다.

import itertools
itertools.combinations(list, n_times)

여기 Python 문서에서 발췌한 것이 당신이 찾고 있는 것을 찾는 데 도움이 될 것입니다.

Combinatoric generators:

Iterator                                 | Results
-----------------------------------------+----------------------------------------
product(p, q, ... [repeat=1])            | cartesian product, equivalent to a 
                                         |   nested for-loop
-----------------------------------------+----------------------------------------
permutations(p[, r])                     | r-length tuples, all possible 
                                         |   orderings, no repeated elements
-----------------------------------------+----------------------------------------
combinations(p, r)                       | r-length tuples, in sorted order, no 
                                         |   repeated elements
-----------------------------------------+----------------------------------------
combinations_with_replacement(p, r)      | r-length tuples, in sorted order, 
                                         | with repeated elements
-----------------------------------------+----------------------------------------
product('ABCD', repeat=2)                | AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
permutations('ABCD', 2)                  | AB AC AD BA BC BD CA CB CD DA DB DC
combinations('ABCD', 2)                  | AB AC AD BC BD CD
combinations_with_replacement('ABCD', 2) | AA AB AC AD BB BC BD CC CD DD

다수의 목록에 대한 모든 조합을 확인하는 가장 좋은 방법은 다음과 같습니다.

import itertools
from pprint import pprint

inputdata = [
    ['a', 'b', 'c'],
    ['d'],
    ['e', 'f'],
]
result = list(itertools.product(*inputdata))
pprint(result)

결과는 다음과 같습니다.

[('a', 'd', 'e'),
 ('a', 'd', 'f'),
 ('b', 'd', 'e'),
 ('b', 'd', 'f'),
 ('c', 'd', 'e'),
 ('c', 'd', 'f')]

또는 쇼트 리스트의 경우 KISS 응답:

[(i, j) for i in list1 for j in list2]

python을 사용하고 있기 때문에 퍼포먼스는 itertools만큼 뛰어나지금은 python을 사용하고 있습니다.

다른 대답도 다 좋아요!

한 줄의 목록 이해를 시도할 수 있습니다.

>>> [name+number for name in 'ab' for number in '12']
['a1', 'a2', 'b1', 'b2']
>>> [name+number for name in 'abc' for number in '12']
['a1', 'a2', 'b1', 'b2', 'c1', 'c2']

인터제이의 답변에 대한 약간의 개선으로, 그 결과를 평범한 목록으로 만들 수 있습니다.

>>> list3 = [zip(x,list2) for x in itertools.permutations(list1,len(list2))]
>>> import itertools
>>> chain = itertools.chain(*list3)
>>> list4 = list(chain)
[('a', 1), ('b', 2), ('a', 1), ('c', 2), ('b', 1), ('a', 2), ('b', 1), ('c', 2), ('c', 1), ('a', 2), ('c', 1), ('b', 2)]

링크에서 참조

itertools「이것들」은 다음과 같습니다.

[(list1[i], list2[j]) for i in range(len(list1)) for j in range(len(list2))]

또는 Python 2의 경우:

[(list1[i], list2[j]) for i in xrange(len(list1)) for j in xrange(len(list2))]

"2개의 목록이 주어지면 각 목록에서 한 항목 쌍으로 가능한 모든 순열을 찾아라"라는 질문에 답하고 기본 Python 기능(즉, 반복 도구 없음)을 사용하여 다른 프로그래밍 언어에 대해 쉽게 복제할 수 있습니다.

def rec(a, b, ll, size):
    ret = []
    for i,e in enumerate(a):
        for j,f in enumerate(b):
            l = [e+f]
            new_l = rec(a[i+1:], b[:j]+b[j+1:], ll, size)
            if not new_l:
                ret.append(l)
            for k in new_l:
                l_k = l + k
                ret.append(l_k)
                if len(l_k) == size:
                    ll.append(l_k)
    return ret

a = ['a','b','c']
b = ['1','2']
ll = []
rec(a,b,ll, min(len(a),len(b)))
print(ll)

돌아온다

[['a1', 'b2'], ['a1', 'c2'], ['a2', 'b1'], ['a2', 'c1'], ['b1', 'c2'], ['b2', 'c1']]

이에 대한 더 나은 답변은 제공된 특정 길이의 목록에만 적용됩니다.

다음은 임의의 길이의 입력에 사용할 수 있는 버전입니다.또한 조합과 순열의 수학적 개념에 관해서도 알고리즘을 명확하게 합니다.

from itertools import combinations, permutations
list1 = ['1', '2']
list2 = ['A', 'B', 'C']

num_elements = min(len(list1), len(list2))
list1_combs = list(combinations(list1, num_elements))
list2_perms = list(permutations(list2, num_elements))
result = [
  tuple(zip(perm, comb))
  for comb in list1_combs
  for perm in list2_perms
]

for idx, ((l11, l12), (l21, l22)) in enumerate(result):
  print(f'{idx}: {l11}{l12} {l21}{l22}')

출력은 다음과 같습니다.

0: A1 B2
1: A1 C2
2: B1 A2
3: B1 C2
4: C1 A2
5: C1 B2

언급URL : https://stackoverflow.com/questions/12935194/permutations-between-two-lists-of-unequal-length

반응형