문자열 내 각 문자가 몇 번 나타나는지 세는 작업은 텍스트 분석, 데이터 정제, 알고리즘 문제 풀이 등 다양한 상황에서 자주 활용됩니다. 이 글에서는 파이썬으로 문자열 내 각 문자의 출현 빈도를 구하는 세 가지 방법을 예제 코드와 실행 결과와 함께 살펴봅니다.
문제 정의
문제: 하나의 문자열이 주어졌을 때, 해당 문자열에 포함된 각 문자가 몇 번 나타나는지 계산해야 합니다.
예를 들어 문자열 "Tutorialspoint"가 주어지면 't'는 2번, 'o'는 2번, 'i'는 2번 나타나고 나머지 문자들은 각각 1번씩 나타납니다. 그럼 세 가지 접근 방식을 하나씩 알아보겠습니다.
방법 1 – 반복문과 딕셔너리를 이용한 기본 구현
가장 직관적인 방법은 문자열을 한 글자씩 순회하면서 딕셔너리에 개수를 누적하는 것입니다. 이미 존재하는 문자라면 값을 1 증가시키고, 처음 등장한 문자라면 새 키로 추가합니다.
예제
test_str = "Tutorialspoint"
# 문자 개수를 저장할 딕셔너리
count_dict = {}
for i in test_str:
# 딕셔너리에 이미 존재하는 문자인 경우
if i in count_dict:
count_dict[i] += 1
# 새로 등장한 문자인 경우
else:
count_dict[i] = 1
print("Tutorialspoint의 모든 문자 개수 :\n " + str(count_dict))
출력
Tutorialspoint의 모든 문자 개수 :
{'T': 1, 'u': 1, 't': 2, 'o': 2, 'r': 1, 'i': 2, 'a': 1, 'l': 1, 's': 1, 'p': 1, 'n': 1}
이 방식은 문자열을 한 번만 순회하므로 시간 복잡도는 O(n)입니다. 외부 라이브러리 없이 동작 원리를 명확하게 이해할 수 있다는 장점이 있습니다.
방법 2 – collections.Counter 모듈 활용하기
파이썬 표준 라이브러리의 collections.Counter는 해시 가능한 객체의 개수를 세도록 설계된 클래스입니다. 단 한 줄로 문자 빈도를 계산할 수 있어 가장 간결한 방법입니다.
예제
from collections import Counter
test_str = "Tutorialspoint"
# collections.Counter()를 사용해 딕셔너리 형태로 결과 생성
res = Counter(test_str)
print("Tutorialspoint의 모든 문자 개수 :\n " + str(dict(res)))
출력
Tutorialspoint의 모든 문자 개수 :
{'T': 1, 'u': 1, 't': 2, 'o': 2, 'r': 1, 'i': 2, 'a': 1, 'l': 1, 's': 1, 'p': 1, 'n': 1}
Counter 객체는 딕셔너리처럼 바로 사용할 수 있으며, most_common()처럼 빈도가 높은 요소를 손쉽게 조회할 수 있는 유용한 메서드도 제공하므로 실무에서 가장 널리 쓰이는 방식입니다.
방법 3 – set()과 딕셔너리 컴프리헨션 활용하기
set()으로 중복을 제거한 고유 문자들을 추출한 뒤, 딕셔너리 컴프리헨션 안에서 str.count()로 각 문자의 개수를 세는 방식입니다.
예제
test_str = "Tutorialspoint"
# set()으로 고유 문자를 추출한 뒤 각 문자의 개수를 계산
res = {i : test_str.count(i) for i in set(test_str)}
print("Tutorialspoint의 모든 문자 개수 :\n " + str(dict(res)))
출력
Tutorialspoint의 모든 문자 개수 :
{'T': 1, 'u': 1, 't': 2, 'o': 2, 'r': 1, 'i': 2, 'a': 1, 'l': 1, 's': 1, 'p': 1, 'n': 1}
다만 count()가 고유 문자마다 문자열 전체를 다시 훑기 때문에 시간 복잡도는 O(n × k)(k는 고유 문자 수)가 됩니다. 짧은 문자열에는 무방하지만 길이가 큰 문자열에서는 방법 1이나 방법 2가 더 효율적입니다.
마무리
이 글에서는 파이썬에서 문자열 내 각 문자의 출현 횟수를 구하는 세 가지 방법을 살펴보았습니다. 학습 목적이라면 방법 1의 반복문 구현이 좋고, 간결함과 성능을 모두 원한다면 방법 2의 Counter를 사용하는 것이 권장됩니다. 상황에 맞는 방법을 골라 활용해 보세요.