Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python – 리스트에서 서로소(Disjoint) 문자열 찾기


여러 리스트에 걸쳐 서로소(disjoint) 관계, 즉 공통으로 포함된 문자가 하나도 없는 문자열 조합을 찾아야 하는 경우가 있습니다. 이럴 때는 두 개의 매개변수를 받는 제너레이터 함수를 정의한 뒤, functools 모듈의 reducelambdaif 조건과 함께 활용하여 결과를 도출할 수 있습니다.

아래는 실제 구현 예제입니다.

예제 코드

from functools import reduce

def determine_disjoint_pairs(disjoint_data, my_result=[]):

    if not disjoint_data and not reduce(lambda a, b: set(a) & set(b), my_result):
        yield tuple(my_result)

    elif disjoint_data:
        yield [idx for k in disjoint_data[0] for idx in determine_disjoint_pairs(disjoint_data[1:], my_result + [k])]


my_list_1 = ["python", "is", "fun"]
my_list_2 = ["its", "awesome", "learning"]

print("The first list is : ")
print(my_list_1)
print("The second list is :")
print(my_list_2)

my_result = list(determine_disjoint_pairs([my_list_1, my_list_2]))

print("The result is :")
print(my_result)

출력 결과

The first list is :
['python', 'is', 'fun']
The second list is :
['its', 'awesome', 'learning']
The result is :
[('fun', 'its'), ('fun', 'awesome')]

동작 원리

  • determine_disjoint_pairs라는 이름의 제너레이터 함수가 정의되며, 이 함수는 두 개의 매개변수를 받습니다.

  • 첫 번째 매개변수(disjoint_data)가 비어 있고, reducelambda를 사용해 계산한 집합 교집합 결과도 거짓(빈 집합)이라면, yield 연산자로 결과를 생성하며 이 값은 튜플(tuple)로 변환됩니다.

  • 그렇지 않고 아직 처리할 데이터가 남아 있다면, 리스트 컴프리헨션(list comprehension)과 함께 yield를 사용하면서, 나머지 데이터와 누적 결과를 새로운 매개변수로 전달해 함수를 재귀적으로 호출합니다.

  • 함수 외부에서는 두 개의 문자열 리스트가 정의되고 콘솔에 출력됩니다.

  • 이 두 리스트를 담은 리스트를 인자로 전달하여 함수를 호출합니다.

  • 호출 결과는 list()로 변환되어 변수에 할당됩니다.

  • 마지막으로 해당 변수가 콘솔에 출력됩니다.

왜 일부 조합만 결과에 포함될까?

출력 결과에서 ('fun', 'its')('fun', 'awesome')만 반환된 이유는, 알고리즘이 두 문자열이 공통 문자를 공유하는지 집합 교집합으로 검사하기 때문입니다. 예를 들어 'python''its'는 모두 문자 't'를 포함하므로 서로소가 아니어서 제외되고, 'fun'은 두 리스트의 어떤 문자열과도 공통 문자가 없어 유효한 조합으로 인정됩니다.