문자 목록에 들어 있는 글자들을 조합해 특정 단어를 만들 수 있는지 확인해야 하는 경우가 종종 있습니다. 이때 파이썬의 all 내장 함수와 count 메서드를 함께 사용하면 아주 간결하게 문제를 해결할 수 있습니다.
핵심 아이디어는 단어를 이루는 각 문자가 필요한 개수만큼 목록에 존재하는지 검사하는 것입니다. all은 모든 조건이 참일 때만 True를 반환하기 때문에 반복 검사를 한 줄로 처리할 수 있습니다.
예제 코드
my_list = ['p', 'p', 'y', 't', 'h', 'p', 'p', 'y', 'n', 'y', 'y', 't']
print("The list is :")
print(my_list)
key = 'pyt'
print("The key is :")
print(key)
my_result = all(key.count(chr) <= my_list.count(chr) for chr in key)
print("The result is :")
if(my_result == True):
print("Word can be constructed. ")
else:
print("Word can't be constructed. ")출력 결과
The list is : ['p', 'p', 'y', 't', 'h', 'p', 'p', 'y', 'n', 'y', 'y', 't'] The key is : pyt The result is : Word can be constructed.
동작 원리
먼저 문자 목록을 정의하고 콘솔에 출력합니다.
구성 가능 여부를 확인할 대상 단어(
key)를 정의하고 출력합니다.제너레이터 표현식을 사용해 단어의 모든 문자를 하나씩 순회합니다.
각 문자마다
key.count(chr)(단어에서 필요한 개수)와my_list.count(chr)(목록에 실제로 있는 개수)를 비교합니다.all내장 함수는 모든 비교 결과가 참일 때만True를 반환하므로, 단어 구성 가능 여부를 한 번에 판단할 수 있습니다.판단 결과를 변수에 저장한 뒤 조건문으로 분기하여 콘솔에 출력합니다.
더 나은 대안: collections.Counter 활용
같은 작업은 collections.Counter로도 처리할 수 있습니다. Counter는 각 문자의 등장 횟수를 세어 주며, 두 Counter 객체의 차집합 연산을 통해 필요한 문자가 부족한지 손쉽게 확인할 수 있습니다.
from collections import Counter
def can_construct(word, letters):
return not (Counter(word) - Counter(letters))
print(can_construct('pyt', ['p', 'p', 'y', 't', 'h'])) # True성능 면에서도 Counter 방식이 유리합니다. list.count()는 호출할 때마다 목록 전체를 훑어야 하므로 O(n×m)의 시간이 걸리지만, Counter는 각 컬렉션을 한 번만 순회하면 되기 때문에 O(n+m)에 처리됩니다. 데이터 크기가 클수록 이 성능 차이가 더욱 벌어집니다.