python programming: data structure

49

Upload: chan-shik-lim

Post on 11-Apr-2017

48 views

Category:

Software


13 download

TRANSCRIPT

Page 1: Python Programming: Data Structure

Python Intermediate Programming

임찬식 ([email protected])

1

Page 2: Python Programming: Data Structure

Python Intermediate Programming타입과 객체

함수와 함수형 프로그래밍

클래스와 객체지향 프로그래밍

데이터 구조

튜닝과 최적화

2

Page 3: Python Programming: Data Structure

데이터 구조프로그램을 작성할 때 도움이 되는 효율적인 데이터 구조 모듈 소개

arraybisect

collectionsitertools

3

Page 4: Python Programming: Data Structure

abc

abc 모듈은 새로운 추상 기반 클래스를 정의하는 데 사용하는메타클래스와 장식자 한 쌍을 가지고 있음

ABCMeta추상 기반 클래스를 나타내는 메타클래스

Python 3

>>> import abc>>> class Stackable(metaclass=abc.ABCMeta):... pass

Python 2

class Stackable: __metaclass__ = abc.ABCMeta

4

Page 5: Python Programming: Data Structure

abc

추상 기반 클래스의 특징

abstracemethod, abstractproperty 장식자를 사용하여메서드나 프로퍼티를 정의하면 실제 구현을 제공할 경우에만인스턴스 생성 가능

어떤 타입을 논리적 하위 클래스로 등록하는 데 사용하는 클래스 메서드register(subclass) 를 가지고 있음

__subclasshook__(cls, subclass) 를 추가로 정의 가능타입 subclass 가 하위 클래스로 간주되면 Truesubclass 가 하위 클래스가 아니면 False

아무런 정보가 없을 경우 NotImplemented 예외를 발생

5

Page 6: Python Programming: Data Structure

abc

abstractmethod(method)method 를 추상 메서드로 선언하는 장식자

직접 상속을 통해 정의한 파생 클래스에서 실제 구현을 제공해야인스턴스 생성 가능

register() 메서드로 등록한 하위 클래스에는 Ý향 없음

abstractproperty(fget [, fset [, fdel [, doc]]])추상 프로퍼티를 생성

매개변수들은 일반 property() 함수와 동일

파생 클래스에서는 해당 프로퍼티 구현을 제공해야 인스턴스 생성 가능

6

Page 7: Python Programming: Data Structure

abc

추상 기반 클래스 정의

>>> from abc import ABCMeta, abstractmethod, abstractproperty>>> class Stackable(metaclass=ABCMeta):... @abstractmethod... def push(self, item):... pass... @abstractmethod... def pop(self):... pass... @abstractproperty... def size(self):... pass

7

Page 8: Python Programming: Data Structure

abc

Stackable 을 상속하여 클래스 생성

>>> class Stack(Stackable):... def __init__(self):... self.items = []... def push(self, item):... self.items.append(item)... def pop(self):... return self.items.pop()...>>> a = Stack()Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: Can't instantiate abstract class Stack with abstract methods size

size() 프로퍼티가 없어 인스턴스를 생성할 수 없음

8

Page 9: Python Programming: Data Structure

abc

size() 프로퍼티를 Stack 에서 상속받은 클래스에 추가

>>> class CompleteStack(Stack):... @property... def size(self):... return len(self.items)...>>> s = CompleteStack()>>> s.push("foo")>>> s.push("bar")>>> s.size2>>> s.pop()'bar'

9

Page 10: Python Programming: Data Structure

array

한 종류의 타입만 담는 객체. 공간 효율적인 자료 구조

array(typecode, [, initializer])

타입 코드 목록

코드 설명 C 타입 크기

'b' 8비트 정수 signed char 1

'B' 8비트 부호 없는 정수 unsigned char 1

'u' 유니코드 문자 PY_UNICODE 2 / 4

'h' 16비트 정수 short 2

'H' 16비트 부호 없는 정수 unsigned short 2

정수형은 머신 아키텍처에 의해 결정10

Page 11: Python Programming: Data Structure

array

코드 설명 C 타입 크기

'i' 정수 int 4 / 8

'I' 부호없는정수 unsigned int 4 / 8

'l' 긴 정수 long 4 / 8

'L' 부호 없는 긴 정수 unsigned long 4 / 8

'q' 더욱 긴 정수 long long 8 (Python 3.3)

'Q' 부호없는 더욱 긴 정수 unsigned long long 8 (Python 3.3)

'f' 단일 정Â도 실수 float 4

'd' 배정Â도 실수 double 8

11

Page 12: Python Programming: Data Structure

array

array 객체와 생성기 표현식을 이용한 데이터 생성

>>> import array>>> a = array.array("i", [1, 2, 3, 4, 5])>>> b = array.array(a.typecode, (x * x for x in a))>>> aarray('i', [1, 2, 3, 4, 5])>>> barray('i', [1, 4, 9, 16, 25])

12

Page 13: Python Programming: Data Structure

array

enumerate() 함수를 이용한 제자리(in‑place) 연산을 통해공간을 절약하는 방식의 프로그래밍 활용

>>> for i, x in enumerate(a):... a[i] = x * x...>>> aarray('i', [1, 4, 9, 16, 25])

13

Page 14: Python Programming: Data Structure

bisect

bisect 모듈은 리스트를 정렬된 순서로 유지하는 데 필요한 기능 제공

bisect(list, item [, low [, high]])insort(list, item [, low [, high]])

bisect(): list 를 정렬된 순서로 유지하기 위해서 item 을list 어디에 삽입해야 하는지 위치 반환

insort(): item 을 list 에 정렬된 순서에 맞게 삽입item 이 이미 존재하면 기존 항목 오른쪽에 삽입

14

Page 15: Python Programming: Data Structure

bisect

>>> from bisect import bisect>>> grades = "FEDCBA">>> breakpoints = [30, 44, 66, 75, 85]>>> grades[bisect(breakpoints, 50)]'D'>>> grades[bisect(breakpoints, 90)]'A'

15

Page 16: Python Programming: Data Structure

bisect

>>> from bisect import insort>>> l = [10, 30, 50, 70]>>> insort(l, 60)>>> l[10, 30, 50, 60, 70]>>> insort(l, 40)>>> l[10, 30, 40, 50, 60, 70]

16

Page 17: Python Programming: Data Structure

collections

유용한 컨테이너 타입에 �한 고성능 구현 함수와다양한 컨테이너를 위한 추상 기반 클래스등을 제공

deque

defaultdictnamedtuple

17

Page 18: Python Programming: Data Structure

deque

양 끝을 가진 객체를 나타내는 컨테이너

>>> from collections import deque>>> d = deque('hello')>>> d.pop()'o'>>> d.pop()'l'>>> ddeque(['h', 'e', 'l'])>>> d.append('a')>>> d.append('b')>>> d.appendleft('c')>>> d.appendleft('d')>>> ddeque(['d', 'c', 'h', 'e', 'l', 'a', 'b'])>>> d.popleft()'d'>>> d.popleft()'c'>>> ddeque(['h', 'e', 'l', 'a', 'b'])

18

Page 19: Python Programming: Data Structure

deque

deque 를 생성할 때 maxlen 인수를 지정하면 정해진 크기를 가진원형 버퍼로 동작

새로운 항목을 추가하는데 공간이 부족하면 반�편에 있는 항목 삭제

deque([1, 2, 3], maxlen=5)>>> d.append(4)>>> d.append(5)>>> ddeque([1, 2, 3, 4, 5], maxlen=5)>>> d.append(6)>>> d.append(7)>>> ddeque([3, 4, 5, 6, 7], maxlen=5)

19

Page 20: Python Programming: Data Structure

deque

deque 는 매우 효율적인 자료 구조

뒤쪽 끝에 항목을 추가하는 작업은 list 보다 약간 느림

하지만, 앞쪽에 항목을 추가하는 작업은 list 보다 매우 빠름

deque 에 새로운 항목을 추가하는 작업은 스레드에서도 안전

pickle 모듈로 직렬화 가능

20

Page 21: Python Programming: Data Structure

defaultdict

없는 키를 처리하는 부분을 제외하고는 dict 와 동일

키를 찾지 못하는 경우에 default_factory 로 지정한 함수 호출

함수는 기본 값을 생성하고 이 값을 해당 키의 값으로 사용

defaultdict 객체는 데이터를 추적하기 위해서사전을 컨테이너로 쓸 때 매우 유용

21

Page 22: Python Programming: Data Structure

defaultdict

>>> from collections import defaultdict>>> s = "yeah but no but yeah but no but yeah">>> words = s.split()>>> word_locations = defaultdict(list)>>> for n, w in enumerate(words):... word_locations[w].append(n)...>>> word_locationsdefaultdict(<class 'list'>, {'yeah': [0, 4, 8], 'but': [1, 3, 5, 7], 'no': [2, 6]})

22

Page 23: Python Programming: Data Structure

이름 있는 튜플

튜플을 사용할 때 불편한 점은 개별 항목을 숫자로만 접근할 수 있다는 것

이러한 불편을 줄이기 위해 이름 있는 튜플(namedtuple)을 제공

namedtuple(typename, fieldnames [, verbose])

이름이 typename 인 tuple 하위 클래스 생성

fieldnames 는 속성 이름 목록 지정유효한 파이썬 식별자여야 함

튜플에 나타날 항목과 동일한 순서로 지정

23

Page 24: Python Programming: Data Structure

이름 있는 튜플

>>> from collections import namedtuple>>> NetworkAddr = namedtuple("NetworkAddr", "hostname port")>>> a = NetworkAddr("www.python.org", 80)>>> a.hostname'www.python.org'>>> a.port80>>> type(a)<class '__main__.NetworkAddr'>>>> len(a)2>>> isinstance(a, tuple)True

24

Page 25: Python Programming: Data Structure

이름 있는 튜플

이름 있는 튜플은 데이터 구조로만 사용될 객체를 정의할 때 유용

name, shares, price 변수를 가진 데이터 구조가 필요할 경우

>>> Stock = namedtuple("Stock", "name shares price")>>> a = Stock("APL", 30, 45.50)>>> aStock(name='APL', shares=30, price=45.5)

25

Page 26: Python Programming: Data Structure

heapq

heapq 모듈은 힙(heap)으로 우선 순위 큐를 구현

힙 조건에 따라 정렬된 항목들의 리스트

heap[0] 은 항상 가장 작은 항목을 담고 있음

0 에서 시작하는 모든 n 에 �해서

heap[n] <= heap[2 * n + 1]

heap[n] <= heap[2 * n + 2] 모두 만족

26

Page 27: Python Programming: Data Structure

heapq

heapify(x)리스트 x 를 제자리에서 힙으로 변환

heappop(heap)힙 조건을 유지하면서 가장 작은 항목을 반환하고 제거힙이 비어있으면 IndexError 발생

heappush(heap, item)힙 조건을 유지하면서 item 을 힙에 추가

heappushpop(heap, item)item 을 힙에 추가하고 힙에서 가장 작은 항목을 제거하는동작을 한 번에 수행

27

Page 28: Python Programming: Data Structure

heapq

heapreplace(heap, item)힙에서 가장 작은 아이템을 반환하고 제거하면서새로운 항목 item 을 추가힙이 비어있으면 IndexError 발생

merge(s1, s2, ...)정렬된 반복 가능한 객체 s1, s2 등을 하나의 정렬된 순서열로 생성

nlargest(n, iterable [, key])iterable 에 있는 가장 큰 n 개의 항목으로 구성된 리스트 생성

nsmallest(n, iterable [, key])iterable 에 있는 가장 작은 n 개의 항목으로 구성된 리스트 생성

28

Page 29: Python Programming: Data Structure

heapq

>>> l = [19, 9, 4, 10, 11, 8, 2]>>> heapq.heapify(l)>>> l[2, 9, 4, 10, 11, 8, 19]>>> heapq.heappop(l)2>>> l[4, 9, 8, 10, 11, 19]>>> heapq.heappop(l)4>>> l[8, 9, 19, 10, 11]>>> heapq.heappush(l, 5)>>> l[5, 9, 8, 10, 11, 19]>>> heapq.heappush(l, 25)>>> l[5, 9, 8, 10, 11, 19, 25]>>>

29

Page 30: Python Programming: Data Structure

heapq

>>> heapq.nlargest(3, l)[25, 19, 11]>>> heapq.nsmallest(3, l)[5, 8, 9]>>> a = [3, 5, 1, 9, 7]>>> b = [6, 4, 8, 2, 10]>>> heapq.heapify(a)>>> heapq.heapify(b)>>> h = heapq.merge(a, b)>>> h.__next__()1>>> h.__next__()2>>> h.__next__()4>>> h.__next__()5

30

Page 31: Python Programming: Data Structure

itertools

itertools 모듈은 데이터에 �해서 다양한 본복을 수행하는 데사용할 수 있는 효율적인 반복자를 생성하는 함수들을 제공

모듈에 있는 모든 함수는 for 문이나 기타 반복자와 관련 있는함수와 함께 사용할 수 있는 반복자를 반환

31

Page 32: Python Programming: Data Structure

chain

chain(iter1, inter2, ..., interN)

반복자 그룹이 주어질 때 모든 반복자를 연결하는 새로운 반복자 생성

>>> for x in chain([1, 2, 3], [4, 5, 6]):... print(x)...123456

32

Page 33: Python Programming: Data Structure

combinations

combinations(iterable, r)

iterable 에서 길이 r 인 모든 하위 순서열을 반환하는 반복자 생성

>>> list(combinations([1, 2, 3, 4], 2))[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]>>> list(combinations([1, 2, 3, 4], 3))[(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]

33

Page 34: Python Programming: Data Structure

count

count([n])

n 에서 시작하는 연속적인 정수를 만드는 반복자 생성

n 을 생략하면 0 에서 시작

sys.maxint 를 넘으면 ‑sys.maxint ‑ 1 에서 다시 시작

>>> g = count()>>> g.__next__()0>>> g.__next__()1>>> g.__next__()2>>> g.__next__()3

34

Page 35: Python Programming: Data Structure

cycle

cycle(iterable)

iterable 에 있는 원소들을 계속해서 순환하는 반복자 생성

>>> g = cycle([1, 2, 3, 4])>>> g.__next__()1>>> g.__next__()2>>> g.__next__()3>>> g.__next__()4>>> g.__next__()1>>> g.__next__()2

35

Page 36: Python Programming: Data Structure

dropwhile

dropwhile(predicate, iterable)

함수 predicate(item) 이 True 로 평가되는 동안iterable 에서 항목을 버리는 반복자 생성

일단 predicate 가 False 를 반환하면 해당 항목과iterable 에 있는 나머지 항목이 생성

>>> s = [10, 20, -3, 5, 3, 6, -5, 7, 15]>>> list(dropwhile(lambda x: x >= 0, s))[-3, 5, 3, 6, -5, 7, 15]

36

Page 37: Python Programming: Data Structure

groupby

groupby(iterable [, key])

iterable 에서 생성되는 연속적인 항목을 그룹 짓는 반복자 생성

그룹을 짓기 위해 중복된 항목 검색

iterable 에서 동일한 항목이 여러 번 나오면 그룹이 생성

>>> g = groupby("aaaabbccddeeefffgg")>>> g.__next__()('a', <itertools._grouper object at 0x10673cd30>)>>> g.__next__()('b', <itertools._grouper object at 0x10673ccf8>)>>> g.__next__()('c', <itertools._grouper object at 0x10673ce80>)

37

Page 38: Python Programming: Data Structure

ifilter (Python3: filter)

ifilter(predicate, iterable)

iterable 에서 predicate(item) 이 True 인 항목만 추출하는 반복자 생성

predicate 가 None 이면 iterable 에 있는 모든 항목이 True 로 평가

>>> s = [10, 15, -3, 5, -6, 7, 15]>>> g = filter(lambda x: x < 0, s)>>> list(g)[-3, -6]

38

Page 39: Python Programming: Data Structure

ifilterfalse (Python3: filterfalse)

ifilterfalse(predicate, iterable)

iterable 에서 predicate(item) 이 False 인 항목만 추출하는 반복자 생성

predicate 가 None 이면 iterable 에 있는 모든 항목이 False 로 평가

>>> from itertools import filterfalse>>> s = [10, 15, -3, 5, -6, 7, 15]>>> g = filterfalse(lambda x: x < 0, s)>>> list(g)[10, 15, 5, 7, 15]

39

Page 40: Python Programming: Data Structure

imap (Python3: map)

imap(function, iter1, iter2, ..., iterN)

function(i1, i2, ..., iN) 들을 수행하는 반복자 생성

>>> a = [1, 2, 4, 10]>>> b = [5, 10, 15, 20]>>> m = map(lambda x, y: x + y, a, b)>>> list(m)[6, 12, 19, 30]>>> m = map(lambda x, y: x + y, a, b)>>> m.__next__()6

40

Page 41: Python Programming: Data Structure

islice

islice(iterable, [start,] stop [, step])

iterable[start:stop:step]이 반환한 것과 비슷한 항목을 추출하는 반복자 생성

>>> s = [10, 15, -3, 5, -6, 7, 15]>>> g = islice(s, 4)>>> g.__next__()10>>> g.__next__()15>>> g.__next__()-3>>> g.__next__()5>>> g.__next__()Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration

41

Page 42: Python Programming: Data Structure

izip (Python3: zip)

izip(iter1, iter2, ... iterN)

(iter1, iter2, ..., iterN) 등 묶어서 사용할 수 있게 해주는 반복자 생성주어진 반복자 중 하나라도 값을 더 이상 생성하지 않으면 반복을 멈춤

>>> a = [1, 3, 5, 7]>>> b = [2, 4, 6, 8]>>> c = [3, 5, 7]>>> g = zip(a, b, c)>>> g.__next__()(1, 2, 3)>>> g.__next__()(3, 4, 5)>>> g.__next__()(5, 6, 7)>>> g.__next__()Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration

42

Page 43: Python Programming: Data Structure

izip_longest (Python3: zip_longest)

izip_longest(iter1, iter2, ..., iterN [,fillvalue=None])

반복자 iter1, iter2, iterN 등을 모두 소진할 때까지 반복이 이어진다는 것을제외하고는 izip() 과 동일

>>> g = zip_longest(a, b, c)>>> g.__next__()(1, 2, 3)>>> g.__next__()(3, 4, 5)>>> g.__next__()(5, 6, 7)>>> g.__next__()(7, 8, None)>>> g.__next__()Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration

43

Page 44: Python Programming: Data Structure

permutaions

permutations(iterable [, r])

iterable 에서 길이 r 인 모든 순열을 반환하는 반복자 생성

r 을 생략하면 iterable 에 있는 항목 수와 동일한 길이로 가정

>>> a = [1, 3, 5, 7]>>> permutations(a, 2)<itertools.permutations object at 0x1066c4f10>>>> list(permutations(a, 2))[(1, 3), (1, 5), (1, 7), (3, 1), (3, 5), (3, 7), (5, 1), (5, 3), (5, 7), (7, 1), (7, 3), (7, 5)]

44

Page 45: Python Programming: Data Structure

product

product(iter1, iter2, ... iterN [, repeat=1])

iter1, iter2 등에 있는 항목들의 데카르트 곱(Cartesian product)을나타내는 튜플을 만들어내는 반복자 생성

>>> a = [1, 3, 5, 7]>>> b = [2, 4]>>> product(a, b)<itertools.product object at 0x106742558>>>> list(product(a, b))[(1, 2), (1, 4), (3, 2), (3, 4), (5, 2), (5, 4), (7, 2), (

45

Page 46: Python Programming: Data Structure

repeat

repeat(object [, times])

object 를 계속해서 만드는 반복자를 생성

times: 반복 횟수 (times 가 없으면 끝없이 반복)

>>> g = repeat([1, 3, 5], 4)>>> g.__next__()[1, 3, 5]>>> g.__next__()[1, 3, 5]>>> g.__next__()[1, 3, 5]>>> g.__next__()[1, 3, 5]>>> g.__next__()Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration

46

Page 47: Python Programming: Data Structure

starmap

starmap(func [, iterable)

func(*item) 들을 만들어내는 반복자 생성

item 은 iterable 에서 가져옴

func() 을 제�로 호출할 수 있는 iterable 에 �해서만 제�로 동작

>>> g = starmap(lambda a, b: a * b, [(1, 2), (2, 3), (3, 4>>> g.__next__()2>>> g.__next__()6>>> g.__next__()12>>> g.__next__()Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration

47

Page 48: Python Programming: Data Structure

takewhile

takewhile(predicate [, iterable])

predicate(item) 이 True 로 평가되는 동안 iterable 에서 항목을 추출하는반복자 생성

predicate 가 False 로 평가되는 즉시 반복을 멈춤

>>> s = [10, 15, -3, 5, -6, 7, 15]>>> g = takewhile(lambda x: x >= 0, s)>>> g.__next__()10>>> g.__next__()15>>> g.__next__()Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration

48

Page 49: Python Programming: Data Structure

tee

tee(iterable [, n])

iterable 에서 n 개의 독립적인 반복자 생성

생성된 반복자들은 n 개 항목 튜플로 반환

n: 기본 값은 2

>>> s = [10, 15, -3, 5, -6, 7, 15]>>> g = tee(s)>>> g[0].__next__()10>>> g[0].__next__()15>>> g[1].__next__()10>>> g[1].__next__()15

49