[Python] collections 모듈의 Counter 클래스

썬구리·2022년 7월 28일
0

Python

목록 보기
1/3
post-thumbnail

파이썬 언어로 프로그래머스 문제를 풀고 나서 다른 사람들은 어떻게 풀었을까? 구경하다가 collection의 Counter 를 활용하여 간결하게 해결한 것을 보고 궁금해져서 찾아보게 되었습니다.

알고보니 collections은 알고리즘을 풀 때 유용하게 쓰이는 라이브러리였고, 앞으로도 요긴하게 쓰일 것 같아 공부하면서 정리하고자 합니다.

이번에는 Counter가 무엇인지 한 번 살펴볼까요?

collections

  • collections 모듈은 일반 자료형 (dict, list, set, tuple) 컨테이너 타입을 발전시킨 형태다.
  • 큐를 구현할 때 사용하는 deque도 지원한다.

Counter

  • 리스트의 원소들이 각각 몇 개인지 카운팅하는 클래스

A Counter is a dict subclass for counting hashable objects. It is a collection where elements are stored as dictionary keys and their counts are stored as dictionary values. Counts are allowed to be any integer value including zero or negative counts. The Counter class is similar to bags or multisets in other languages.

공식레퍼런스 참고

  • Counter 는 해시 가능한 객체들을 카운팅하는 딕셔너리의 하위 클래스다.
  • key와 value를 한 쌍으로 저장하는 자료형인 딕셔너리 형태로 반환한다. {문자:개수}
  • 딕셔너리에서 제공하는 API를 그대로 사용할 수 있다.

collections.Counter 사용법

from collections import Counter

기본적으로 파이썬에 내장되어있는 함수이기 때문에, 따로 설치가 필요없이 import만 하면 된다.

1. List

cnt = Counter()
for word in ['wine', 'soju', 'wine', 'beer', 'soju', 'soju']:
    cnt[word] += 1

print(cnt)

>>> Counter({'soju': 3, 'wine': 2, 'beer': 1})
arr = ['wine', 'soju', 'wine', 'beer', 'soju', 'soju', 'beer']
print(Counter(arr))

>>> Counter({'soju': 3, 'wine': 2, 'beer': 2}) # 2
  • 개수가 많은 순서대로 나열하는 것을 알 수 있다.
  • 리스트의 모든 요소의 개수를 세서 dictionary로 출력하기를 원할 때 쓰면 좋다.

2. Dictionary

dic = {'wine': 5, 'soju': 7, 'beer':2}
print(Counter(dic))

>>> Counter({'soju': 7, 'wine': 5, 'beer': 2})
  • 딕셔너리도 Count를 쓸 수 있다.
  • 개수가 많은 순서대로 나열하는 것을 알 수 있다.

3. 문자열

c = Counter('chardonnay')
print(c)

>>> Counter({'a': 2, 'n': 2, 'c': 1, 'h': 1, 'r': 1, 'd': 1, 'o': 1, 'y': 1})
  • 문자열의 문자 개수가 많은 순서대로 나열하는 것을 알 수 있다.

4. value = count

c = Counter(sake=4, makgeolli=8)
print(c)

>>> Counter({'makgeolli': 8, 'sake': 4})
  • value = count 형태 또한 개수가 많은 순서대로 나열하는 것을 알 수 있다.

5. 카운트 반환

c = Counter(['eggs', 'ham'])
print(c['bacon']) # 0
print(c['eggs']) # 1개가 존재하므로 카운팅 1

>>> 0
>>> 1
  • 누락된 항목에 대해 KeyError 를 발생시키는 대신 0을 반환

6. 요소 제거

c['ham'] = 0
print(c)

>>> Counter({'eggs': 1, 'ham': 0}) 
# 요소 제거
del c['ham']
print(c)

>>> Counter({'eggs': 1}) 
  • 개수를 0으로 설정해도 요소는 제거되지 않음을 알 수 있다.
  • del을 사용하면 요소가 제거된다.

Counter의 메소드들

1. elements()

  • 입력된 각각 요소의 개수만큼 풀어서 반환
  • 1보다 작으면 무시
  • sorted : 오름차순으로 정렬
c = Counter(a=4, b=2, c=0, d=-2)
sorted(c.elements()) 

>>> ['a', 'a', 'a', 'a', 'b', 'b']

2. most_common([n])

  • 최빈값 n개를 반환
  • 빈값이면 요소 전체를 반환
  • 튜플 ('value', count) 형태의 리스트로 반환
Counter('abracadabra').most_common(3)
Counter('abracadabra').most_common()

>>> [('a', 5), ('b', 2), ('r', 2)]
>>> [('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]

3. subtract()

  • 요소를 빼준다.
  • 요소가 없는 경우, 음수의 값이 반환된다.
c = Counter(a=4, b=2, c=0, d=-2)
d = Counter(a=1, b=2, c=3, d=4, e=5)
c.subtract(d)
print(c)

>>> Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6, 'e': -5})

4. total()

  • 요소의 총합
Counter(a=10, b=5, c=0).total()

>>> 15

덧셈(+), 뺄셈(-)

  • Counter는 덧셈과 뺄셈 연산을 지원합니다.
  • 뺄셈은 음수 결과를 제외합니다.
c = Counter('banana')
d = Counter('tomato')

print(c + d)
print(c - d)

>>> Counter({'a': 4, 'n': 2, 't': 2, 'o': 2, 'b': 1, 'm': 1})
>>> Counter({'a': 2, 'n': 2, 'b': 1})

교집합(&), 합집합(|)

  • Counter는 교집합과 합집합을 지원합니다.
  • 교집합 : 공통요소의 최소 개수를 반환
  • 합집합 : 공통요소 중 최대 개수를 반환
c = Counter('banana')
d = Counter('tomato')

print(c & d)
print(c | d)

>>> Counter({'a': 1})
>>> Counter({'a': 3, 'n': 2, 't': 2, 'o': 2, 'b': 1, 'm': 1})

Review

list 뿐만 아니라 문자열을 넣어도 데이터가 몇 개인지 딕셔너리 형태로 알려주는 것이 신기했다.
다양한 메소드를 지원해주는 것도 마음에 들고 덧셈, 뺄셈, 교집합, 합집합 등 연산이 가능하다는 것 또한 매력적으로 다가왔다.
특히 most_common()가 마음에 들었는데, 사람들이 가장 많이 쓴 단어가 무엇인지 궁금할 때 쓰면 재밌을 것 같다.
Counter는 딕셔너리를 확장한 것이므로 제대로 쓰기 위해서는 기본적인 딕셔너리 활용도 잘해야겠다는 생각이 들었다.

profile
맛있는 개발파이

0개의 댓글