데이터의 개수를 셀 때 매우 유용한 파이썬의 collections 모듈의 Counter 클래스
Hash와 같이 알고리즘 문제를 풀 때에도 유용하게 사용할 수 있다.
collections 모듈의 Counter 클래스는 별도 패키지 설치 없이 파이썬만 설치되어 있다면 다음과 같이 임포트해서 바로 사용할 수 있다.
from collections import Counter
Counter 생성자는 여러 형태의 데이터를 인자로 받는다. 먼저 중복된 데이터가 저장된 배열을 인자로 넘기면 각 원소가 몇 번씩 나오는지가 저장된 객체를 얻게 된다.
>>> Counter(['red', 'blue', 'red', 'green', 'blue', 'blue'])
Counter({'blue': 3, 'red': 2, 'green': 1})
Counter 생성자에 문자열을 인자로 넘기면 각 문자가 문자열에서 몇 번씩 나타나는지를 알려주는 객체가 반환된다.
>>> Counter("hello world")
Counter({'h': 1, 'e': 1, 'l': 3, 'o': 2, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
>>> counter = Counter("hello world")
>>> counter
Counter({'h': 1, 'e': 1, 'l': 3, 'o': 2, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
>>> counter["o"], counter["l"]
(2, 3)
2.특정 키에 해당하는 값을 갱신할 수도 있다.
counter["l"] += 100
counter["h"] -= 1
counter
Counter({'h': 0, 'e': 1, 'l': 103, 'o': 2, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
>>> o in counter
True
>>> o not in counter
False
Counter 클래스는 가장 흔한 데이터 찾는 것과 같은 작업을 좀 더 쉽게 할 수 있도록, 데이터의 개수가 많은 순으로 정렬된 배열을 리턴하는 most_common()이라는 메서드를 제공하고 있다.
from collections import Counter
Counter('hello world').most_common()
[('l', 3), ('o', 2), ('h', 1), ('e', 1), (' ', 1), ('w', 1), ('r', 1), ('d', 1)]
이 메서드의 인자로 숫자 K를 넘기면 그 숫자 만큼만 리턴하기 때문에, 가장 개수가 많은 K개의 데이터를 얻을 수도 있다.
from collections import Counter
Counter('hello world').most_common(2)
[('l', 3), ('o', 2)]
import re
words = re.findall(r'\w+',open('hamlet.txt').read().lower())
Counter(words).most_common(10)
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
('you', 554), ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]
counter1 = Counter(["A", "A", "B"])
counter2 = Counter(["A", "B", "B"])
counter1 + counter2
Counter({'A': 3, 'B': 3})
counter1 - counter2
Counter({'A': 1})
단, 뺄샘의 결과로 0이나 음수가 나온 경우에는 최종 카운터 객체에서 제외가 되니 이 부분 주의해서 사용해야 한다.
예시 : 프로그래머스 완주하지 못한 선수
해쉬를 사용하는 알고리즘 문제에 Counter는 데이터 개수를 구할 수 있다는 이점을 활용하여 문제를 푸는 데 도움이 된다.
입력값 : ["mislav", "stanko", "mislav", "ana"], ["stanko", "ana", "mislav"]
from collections import Counter
def solution(participant, completion):
answer = ''
p_dict = Counter(participant) # 참가자 배열을 Counter로 만듬
print(p_dict)
c_dict = Counter(completion) # 완주자 배열을 Counter로 만듬
print(c_dict)
for p_name in p_dict:
if p_dict[p_name] != c_dict[p_name]: # 완주자 Counter에 없거나 개수가 맞지 않는 이름을 반환
answer = p_name
return answer
Counter({'mislav': 2, 'stanko': 1, 'ana': 1})
Counter({'stanko': 1, 'ana': 1, 'mislav': 1})
〉 "mislav"
https://www.daleseo.com/python-collections-counter/
파이썬 공식 레퍼런스 문서
https://docs.python.org/3/library/collections.html#collections.Counter