파이썬 모듈 관광 4회: 기본제공 자료구조 겉핥기!

오늘은 파이썬에서 기본으로 제공하는 자료구조가 어떤
것이 있는지 겉핥기식으로 쭉 고속으로 관광가겠습니다~ 🙂

내장 자료구조

우선 기본 내장자료구조 str, unicode, list, tuple, dict, set 여섯가지에서 아무 기능이나 하나씩 써 봅시다. ^.^;

>>> '6,7-dihydro-1-methyl-7-oxo-3-propyl'.partition('-')
('6,7', '-', 'dihydro-1-methyl-7-oxo-3-propyl')

>>> u'def\ttest()'.expandtabs()   # unicode 타입
u'def     test()'

>>> l = [1, 2, 3, 4]   # list 타입
>>> l.sort(key=lambda v: - v**2 % 5)
>>> l
[2, 3, 1, 4]

>>> t = 3, 4    # tuple 타입
>>> t * 5
(3, 4, 3, 4, 3, 4, 3, 4, 3, 4)

>>> d = dict.fromkeys('12345')
>>> d.update({'4': 1, '6': 2})
>>> d
{'1': None, '3': None, '2': None, '5': None, '4': 1, '6': 2}

>>> set('TOMMARVOLORIDDLE') - set('IAMLORDVOLDEMORT')
set([])

밑의 타입들은 보통 다른 언어에서는 자료구조라기보다는 그냥 primitive 타입이지만 그래도 그냥 나머지도 끼워줘 봅시다;

>>> map((5).__mul__, range(3))  # int/long 타입
[0, 5, 10]

>>> (1+5j)**2           # complex 타입
(-24+10j)

>>> divmod(5.3, 3.1)    # float 타입
(1.0, 2.1999999999999997)
>>> bf = buffer('ARNDCQEGHILKMFPSTWYVBZX', 5, 500)
>>> len(bf), bf[:3]     # buffer 타입 (사실은 C 모듈에 붙어야 유용..)
(18, 'QEG')

>>> s = slice(1, 10, 2)
>>> 'ARNDCQEGHILKMFPSTWYVBZX'[s]
'RDQGI'

bool, frozenset 등등은 그냥 넘어갑시다 -ㅇ-;

이제 기본 자료형을 보았으니 다음으로 표준 확장 모듈 자료구조들을..

표준 라이브러리 자료구조

작은 값을 많이 저장할 때 효율적으로 메모리또는 디스크에 들고 있을
수 있는 array
모듈입니다.

>>> import array
>>> arr = array.array('h')
>>> arr.append(123)
>>> arr.extend([34,5,8])
>>> arr.tostring()
'{\x00"\x00\x05\x00\x08\x00'
>>> arr.tofile(open('myarr', 'w'))
>>> arr.pop()
8

heapq
모듈은 기본 list자료형을 가지고 우선순위 큐(priority queue)
쓸 수 있게 해줍니다. 스케줄링 루틴 같은 곳에서 정말 편리합니다.
속도가 무진장 빠릅니다. 🙂

>>> import heapq
>>> l = list(['ham', 'egg', 'spam', 'britney', 'guido'])
>>> heapq.heapify(l)
>>> heapq.nlargest(1, l)
['spam']
>>> heapq.nsmallest(2, l)
['britney', 'egg']
>>> map(heapq.heappop, [l]*5)
['britney', 'egg', 'guido', 'ham', 'spam']

bisect
모듈은 정렬된 list에서 이진검색법으로 자료의 위치를 찾아줍니다.
dict로 다루기에는 자료의 양이 많거나, 순서가 중요한 경우에 쓸만합니다.
아래 예제는 동전을 몇 번 던지면 앞면이 나오나 같은 경우를 나타내는

기하분포
랜덤함수를 bisect로 만든 방법인데, 그냥 계산해버리는
방법도 있지면 예제를 위해서 –; (실제로 분포함수가 없고 그냥 이산확률만
덩그러니 주어졌을 때 bisect가 꽤 쓸만합니다.)

>>> import bisect, random
>>> geometric_cdf = lambda p, k: 1 - (1 - p)**k
>>> cumprob = map(geometric_cdf, [0.5] * 20, range(20))
>>> cumprob[:10]
[0.0, 0.5, 0.75, 0.875, 0.9375, 0.96875, 0.984375, 0.9921875, 0.99609375, 0.998046875]
>>> georand = lambda: bisect.bisect_left(cumprob, random.random())
>>> [georand() for i in range(15)]
[1, 1, 1, 4, 2, 1, 2, 1, 1, 1, 2, 2, 2, 1, 1]

다음은 어정쩡한 이름을 달고 있는
collections
입니다.

>>> import collections
>>> counter = collections.defaultdict(lambda: 0)
>>> for c in 'wii tennis':
...     counter[c] += 1
... 
>>> counter.items()
[(' ', 1), ('e', 1), ('i', 3), ('n', 2), ('s', 1), ('t', 1), ('w', 1)]

>>> dq = collections.deque()
>>> dq.append(1); dq.append(2)
>>> dq.appendleft(3)
>>> dq
deque([3, 1, 2])
>>> dq.pop()
2
>>> dq.popleft()
3
>>> dq
deque([1])

빼놓으면 서운하니까
bsddb
도 한 번..

>>> import bsddb
>>> hdb = bsddb.hashopen('test', 'c')
>>> hdb['byam'] = 'uhung`'
>>> hdb.keys()
['byam']
>>> del hdb['byam']
>>> hdb.close()

>>> rndb = bsddb.rnopen('test2', 'c')
>>> rndb[1] = 'sujiniya'
>>> rndb[3] = 'geosigi'
>>> rndb.items()
[(1, 'sujiniya'), (3, 'geosigi')]
>>> rndb[2] = 'wae?'
>>> rndb.items()
[(1, 'sujiniya'), (2, 'wae?'), (3, 'geosigi')]

>>> # B+Tree는 너무 똑같은 것 계속하면 지루해서 생략 -ㅇ-;

이 외에도
UserString,
UserDict,
StringIO,
decimal,
Queue
등 유용한 것이 많이 있습니다만, 신비감 조성을 위해서 모두 소개하지 않고
이쯤에서 마칩니다. =3=33

2 thoughts on “파이썬 모듈 관광 4회: 기본제공 자료구조 겉핥기!”

  1. 일 년 전에 이 글이 있었다면 얼마나 좋았을까요. ㅠ.ㅠ; 몸으로 부딧히며 생짜로 구현했다가 더 좋은게 기본적으로 있다는걸 알고 좌절하기 수십번-_-

    슬플 뿐입니다. ㅎㅎ

  2. 파이썬 관광모듈 아주 흥미롭게 보고 있습니다. 이번회는 제게 아주 유용해서 좋은 글 감사드립니다. Python이 computational science에 강하다(?)는 얘길 여기저기서 듣고, 무척이나 관심있게 보고 있습니다.

    Python를 computational science(optimization-linear/integer/dynamic programming, simulation)에서 효과적으로 쓰기 위한 tool (IDE, editor, debugger, popular APIs) 들도 한번 소개해주심 너무 좋겠습니다.

Comments are closed.