Asterisk(별표)

Asterisk(*, 별표)는 단순 곱셈, 제곱 연산 등에 주로 사용된다. 또한, 몇 개의 인자가 들어올지 모르는 상황에서 가변 인자에 활용하기도 한다. 여기서 주로 볼 것은 가변 인자에 사용하는 상황이다.

>>> def asterisk_test(a, *args):
...     print(a, args)
...     print(type(args))
... 
>>> asterisk_test(1, 2, 3, 4, 5, 6)
1 (2, 3, 4, 5, 6)
<class 'tuple'>

*args라는 변수에 2, 3, 4, 5, 6이 튜플로 묶여서 들어간 것을 볼 수 있다.

값에 해당하는 변수를 지정해주는 키워드 인자의 경우에는 딕셔너리 타입으로 묶여서 들어가며, 보통 별표를 2개 사용한다.

>>> def asterisk_test(a, **kargs):
...     print(a, kargs)
...     print(type(kargs))
... 
>>> asterisk_test(1, b=2, c=3, d=4, e=5, f=6)
1 {'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
<class 'dict'>

별표는 unpacking에서도 사용할 수 있다. 튜플이나 딕셔너리에 들어가 있는 값들을 풀어서 zip등에 유용하게 사용할 수 있다(선형 대수 파트에 가면 정말 유용하다는 것을 깨닫게 될 것이다).

>>> def asterisk_test(a, args):
...     print(a, *args)
...     print(type(args))
... 
>>> asterisk_test(1, (2, 3, 4, 5, 6))
1 2 3 4 5 6
<class 'tuple'>

zip을 활용한 간단한 예시이다.

>>> data = ([1, 2], [3, 4], [5, 6])
>>> print(*data)
[1, 2] [3, 4] [5, 6]
>>> for datum in zip(*data):
...     print(sum(datum))
... 
9
12

data 리스트에 들어있는 튜플들이 별표에 의해 풀리게 된다. 그리고 각 튜플의 요소들은 zip()에 의해 하나씩 추출되며, sum()으로 더해진다. (1, 3, 5)가 더해져 9, (2, 4, 6)이 더해져 12가 도출된다.


Collections

collection 모듈에는 리스트, 튜플, 딕셔너리에 대한 확장 자료구조들이 들어있다. 기존 전통적인 자료구조를 사용자가 조금 더 편리하게 사용할 수 있다. 이걸 왜 이제 알았지

from collections import deque
from collections import Counter
from collections import OrderedDict
from collections import defaultdict


Collections - deque

deque는 스택과 큐를 지원하는 모듈이다. 메모리 구조 측면에서 리스트에 비해 매우 효율적이며 rotate(), reverse()등의 특성도 지원한다.

>>> from collections import deque
>>> deque_list = deque()
>>> for i in range(5):
...     deque_list.append(i)      # deque_list에 추가
... 
>>> print(deque_list)
deque([0, 1, 2, 3, 4])

>>> deque_list.appendleft(10)     # deque_list의 가장 왼쪽에 추가
>>> print(deque_list)
deque([10, 0, 1, 2, 3, 4])

>>> deque_list.rotate(2)          # 두 번 rotate(1. 4가 맨 앞으로 이동, 2. 3이 맨 앞으로 이동)
>>> print(deque_list)
deque([3, 4, 10, 0, 1, 2])

>>> print(deque(reversed(deque_list)))    # 뒤집자
deque([2, 1, 0, 10, 4, 3])


Collections - OrderedDict

일반적인 파이썬 딕셔너리에서는 데이터를 입력한 순서대로 반환되지 않는다. 하지만 OrderedDict를 사용하면 저장한 순서대로 저장된다.

>>> from collections import OrderedDict
>>> d = OrderedDict()
>>> d['x'] = 100
>>> d['y'] = 200
>>> d['z'] = 300
>>> d['l'] = 500
>>> 
>>> for k, v in d.items():
...     print(k, v)
... 
x 100
y 200
z 300
l 500

딕셔너리의 값을 value나 key 기준으로 정렬할 때 편리하다.

>>> for k, v in OrderedDict(sorted(d.items(), key=lambda t:t[0])).items():
...     print(k, v)
... 
l 500
x 100
y 200
z 300


Collections - defaultdict

defaultdict는 딕셔너리의 값에 기본 값을 지정해줄 수 있다. 보통 딕셔너리에 key에 해당하는 value를 지정해주기 전까지는 key에 해당하는 value를 출력하려고 하면 오류가 생긴다. 이를 방지하는 것이 defaultdict이다.

>>> from collections import defaultdict
>>> d = defaultdict(object)
>>> d = defaultdict(lambda: 0)    # 기본 값 지정
>>> print(d['first'])
0

lambda로 기본 값을 0으로 지정하였다.

어떻게 유용하게 사용할 수 있을까? 바로 단어의 개수를 셀 때이다. 딕셔너리를 이용해 단어의 개수를 셀 때, 처음 등장하는 단어는 조건문을 이용해 따로 최초값(1)을 지정해주어야 한다. 하지만 defaultdict를 이용하면 조건문이 필요 없다.

>>> from collections import defaultdict
>>> word_count = defaultdict(object)
>>> word_count = defaultdict(lambda: 1)
>>> for word in text:
...     word_count[word] += 1


Collections - Counter

Counter의 기능은 가히 혁신에 가깝다. Counter는 sequence 타입의 데이터 요소의 개수를 딕셔너리 형태로 반환해준다. 쉽게 말해, 단어 개수 세기를 자동으로 수행해주는 녀석이다.

>>> from collections import Counter
>>> c = Counter()
>>> c = Counter('gallahad')
>>> print(c)
Counter({'a': 3, 'l': 2, 'g': 1, 'h': 1, 'd': 1})

당연히 긴 문장에서 단어 개수를 세는 것도 문제 없다. 또한, 텍스트 뿐만 아니라 딕셔너리, 키워드 변수들도 모두 처리 가능하다. 다음은 딕셔너리에서의 처리 예시이다. 리스트를 아주 쉽게 만들 수 있다.

>>> from collections import Counter
>>> c = Counter({'red': 4, 'blue': 2})
>>> print(c)
Counter({'red': 4, 'blue': 2})
>>> print(list(c.elements()))
['red', 'red', 'red', 'red', 'blue', 'blue']



별도의 출처 표시가 있는 이미지를 제외한 모든 이미지는 강의자료에서 발췌하였음을 밝힙니다.

댓글남기기