숫자로 이루어진 리스트가 있고, 그중 일부 요소는 여러 번 반복해서 나타난다고 가정해 보겠습니다. 이때 각 요소 자체와 그 요소가 등장한 횟수를 한 쌍으로 묶어 [요소, 개수] 형태의 하위 리스트로 만들고 싶다면 어떻게 해야 할까요?
이 글에서는 두 가지 대표적인 방법을 소개합니다. 첫 번째는 반복문과 append()를 직접 활용하는 방식이고, 두 번째는 표준 라이브러리인 collections 모듈의 Counter를 활용하는 더 간결한 방식입니다.
방법 1: for 루프와 append() 활용
이 방식은 리스트의 각 요소를 그 뒤에 있는 모든 요소와 하나씩 비교합니다. 일치하는 항목이 있으면 카운트를 증가시키고, 마지막에 해당 요소와 개수를 함께 하위 리스트로 만들어 결과 리스트에 추가합니다. 이미 처리한 요소는 다시 세지 않도록 별도의 리스트로 관리하면 중복 없이 깔끔한 결과를 얻을 수 있습니다.
예제 코드
def occurrences(listA):
counted = [] # 이미 집계한 요소 저장
result = [] # 최종 결과 리스트
for i in range(len(listA)):
if listA[i] not in counted:
counted.append(listA[i])
count = 0
# 같은 값을 가진 항목 개수 세기
for j in range(len(listA)):
if listA[i] == listA[j]:
count += 1
result.append([listA[i], count])
return result
# 호출 코드
listA = [13, 65, 78, 13, 12, 13, 65]
print("리스트 내 각 요소의 발생 횟수:\n")
print(occurrences(listA))실행 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
리스트 내 각 요소의 발생 횟수: [[13, 3], [65, 2], [78, 1], [12, 1]]
결과를 보면 13은 3번, 65는 2번, 78과 12는 각각 1번 나타났음을 확인할 수 있습니다.
방법 2: collections.Counter 활용
두 번째 방법은 collections 모듈의 Counter 클래스를 사용하는 것입니다. Counter에 리스트를 전달하면 각 요소의 등장 횟수가 자동으로 계산됩니다. 이후 딕셔너리의 키(요소)와 값(개수)을 순회하면서 새로운 리스트에 [요소, 개수] 쌍을 추가하면 됩니다.
예제 코드
from collections import Counter
def occurrences(listA):
c = Counter(listA)
new_list = []
for k, v in c.items():
new_list.append([k, v])
return new_list
listA = [13, 65, 78, 13, 12, 13, 65]
print("리스트 내 각 요소의 발생 횟수:\n")
print(occurrences(listA))실행 결과
위 코드를 실행하면 동일한 결과를 얻을 수 있습니다.
리스트 내 각 요소의 발생 횟수: [[13, 3], [65, 2], [78, 1], [12, 1]]
어떤 방법을 선택해야 할까?
직접 구현하는 첫 번째 방법은 로직을 이해하는 데 도움이 되지만, 이중 루프 때문에 시간 복잡도가 O(n²)이므로 데이터가 많아지면 성능이 떨어집니다. 반면 Counter를 사용하는 두 번째 방법은 코드가 훨씬 짧고 가독성이 좋으며, 내부적으로 최적화되어 있어 대용량 데이터에서도 효율적으로 동작합니다. 실무에서는 특별한 이유가 없다면 Counter 사용을 권장합니다.