문제 소개
단어 목록이 주어졌을 때, 같은 단어가 여러 번 반복해서 나타날 수 있습니다. 이때 각 단어가 몇 번 등장했는지 그 빈도(frequency)를 구하고, 동시에 서로 다른 고유 단어(distinct words)가 총 몇 개인지 세는 프로그램을 만들어 보겠습니다.
예를 들어 입력이 다음과 같다고 가정해 봅시다.
words = ["Book", "Sound", "Language", "Computer", "Book", "Language"]
이 경우 출력은 (4, '2 1 2 1')이 됩니다. 고유 단어는 총 4개이고, 첫 번째 단어(Book)와 세 번째 단어(Language)가 두 번씩 등장했기 때문입니다.
해결 접근 방법
이 문제는 파이썬의 OrderedDict를 사용하면 깔끔하게 해결할 수 있습니다. OrderedDict는 일반 딕셔너리와 달리 항목이 삽입된 순서를 그대로 유지하므로, 단어가 처음 등장한 순서대로 빈도를 기록할 수 있다는 장점이 있습니다.
풀이 과정은 다음과 같습니다.
- 삽입 순서를 유지하는
OrderedDict객체d를 생성합니다. - 단어 목록의 각 단어
w에 대해 다음을 수행합니다.w가 이미d에 존재하면 해당 값을 1 증가시킵니다.- 존재하지 않으면 새 키로 추가하고 값을 1로 설정합니다.
- 마지막으로
d의 키(고유 단어) 개수와, 모든 빈도 값을 공백으로 연결한 문자열을 튜플 형태로 반환합니다.
구현 예제
아래 코드를 통해 실제 동작을 확인해 보겠습니다.
from collections import OrderedDict
def solve(words):
d = OrderedDict()
for w in words:
if w in d:
d[w] += 1
else:
d[w] = 1
return len(d.keys()), ' '.join([str(d[k]) for k in d.keys()])
words = ["Book", "Sound", "Language", "Computer", "Book", "Language"]
print(solve(words))입력
["Book", "Sound", "Language", "Computer", "Book", "Language"]
출력
(4, '2 1 2 1')
추가 팁: Counter 활용하기
참고로 파이썬 3.7 이상에서는 일반 dict도 삽입 순서를 보장하므로, collections.Counter를 사용하면 위 로직을 한 줄로 더 간결하게 작성할 수 있습니다.
from collections import Counter def solve(words): c = Counter(words) return len(c), ' '.join(str(v) for v in c.values())
두 방법 모두 결과는 동일하며, 상황에 맞게 선택하여 사용하면 됩니다.