- 강의 목록
-Python Data Structure
-Python code
- 요약
강의
파이썬에서 사용할 수 있는 자료구조와, Collections에서 사용할 수 있는 자료구조들에 대해 학습했다.
피어세션
모더레이터의 발표 및 질의응답 형식을 통해 전날 받은 수업을 복습하는 시간을 가졌다.
또한 모더레이터의 코드를 기준으로 과제 풀이를 하며 더 나은 풀이방법을 깨닫는 시간을 가졌다.
- 학습정리
스택 (Stack)
- 마지막에 삽입한 데이터를 먼저 반환하도록 설계된 구조 (LIFO)
- Data의 입력을 Push, 출력을 Pop이라고 한다.
- 리스트를 사용해 스택 구조를 구현할 수 있다.
- 리스트의 append()와 pop() 함수를 사용하여 구현 가능
큐 (Queue)
- 먼저 넣은 데이터를 먼저 반환하도록 설계된 구조 (FIFO)
- Stack과 반대되는 개념
- 리스트를 사용해 큐 구조를 활용할 수 있다.
- 리스트의 append()와 pop(0)을 사용하여 구현 가능
튜플 (Tuple)
- 값의 변경이 불가능한 리스트
- 선언 시 [] 가 아닌 ()를 사용
- 하나만 넣을경우 (1)이 아니라 (1, )로 할 것.
- 리스트의 연산, 인덱싱, 슬라이싱 등을 동일하게 사용할 수 있다.
- 변경되지 않은 데이터를 저장하여 사용자의 실수에 의한 에러를 사전에 방지하기 위해 사용된다.
집합 (Set)
- 값을 순서없이 저장하고 중복을 불허하는 자료형
- set 객체 선언을 이용해 객체를 생성하거나, {}를 활용해 생성할 수 있다.
- 수학에서 사용하는 다양한 집합연산이 가능하다.
- remove 함수는 존재하지 않은 것을 삭제할 경우 에러가 발생하지만 discard는 에러가 발생하지 않는다.
add | 추가 | discard | 삭제 |
remove | 삭제 | clear | 전체 삭제 |
update | 수정 | union | 합집합 |
intersection | 교집합 | difference | 차집합 |
사전 (Dict)
- 데이터를 저장할 때 구분지을 수 있는 값과 함께 저장
- 구분을 위한 데이터 고유값을 Identifier 또는 Key라고 한다.
- Key 값을 활용해 데이터 값(Value)를 관리한다.
- Key와 Value를 매칭하여 Key로 Value를 검색한다.
- 다른 언어에서는 Hash Table이라는 용어를 사용한다.
Collections
- List, Tuple, Dict에 대한 Python Built-in 확장 자료구조 (모듈)
- 편의성, 실행 효율 등을 사용자에게 제공한다.
collections.deque()
- Stack과 Queue를 지원하는 모듈
- List에 비해 빠른 자료 저장 방식을 지원함.
- rotate, reverse 등 Linked List의 특성을 지원함
- 기존 List 형태의 함수를 모두 지원함.
- 효율적 메모리 구조로 처리 속도 향상
#--deque--#
from collections import deque
#선언
deque_list = deque()
#추가
for i in range(5) : deque_list.append(i)
print(deque_list)
deque_list.appendleft(10) #왼쪽에 추가
print(deque_list)
deque_list.extend([1,2,3]) #extendleft도 있음.
print(deque_list)
#삭제
print(deque_list.pop())
print(deque_list)
print(deque_list.popleft())
print(deque_list)
#회전
deque_list.rotate(2) #파라미터만큼 회전
# 12345=>rotate(2)=>34512 만약 음수면 반대로 회전
print(deque_list)
collections.OrderedDict()
- 데이터를 입력한 순서대로 dict 반환
- 원래 dict는 입력한 순서를 보장하지 않았으나 3.6부터 순서 보장한다.
- dict type 값을 value 또는 key 값으로 정렬할 때 사용 가능
#--ordereddict--#
from collections import OrderedDict
d = OrderedDict({'a':100, 'c':200, 'b':300, 'd':400})
print(d) #OrderedDict([('a', 100), ('c', 200), ('b', 300), ('d', 400)])
#반환
#True : LIFO / False : FIFO
d.popitem(True)
print(d) #OrderedDict([('a', 100), ('c', 200), ('b', 300)])
d.popitem(False)
print(d) #OrderedDict([('c', 200), ('b', 300)])
#이동
#True : 맨 오른쪽으로 / False : 맨 왼쪽으로
d.move_to_end('c', True)
print(d) #OrderedDict([('b', 300), ('c', 200)])
d.move_to_end('c',False)
print(d) #OrderedDict([('c', 200), ('b', 300)])
#키값 정렬
for k,v in OrderedDict(sorted(d.items(), key=lambda t:t[0])).items():
print(k, v)
print('---------')
#밸류값 정렬
for k, v in OrderedDict(sorted(d.items(), key=lambda t: t[1])).items():
print(k, v)
collections.defaultdict()
- dict type 값에 기본 값을 지정하여 신규값 생성시 사용
- dict에도 dict.setdefault()가 있다. 하지만 defaultdict가 훨씬 간단하고 빠르다.
#--defaultdict--#
from collections import defaultdict
d = defaultdict()
d = defaultdict(lambda : 0) #디폴트 값을 0으로 설정
print(d["a"])
print(d) #별도로 추가하지 않았음에도 자동으로 추가됨
collections.Counter()
- sequence type의 data element들의 개수를 dict 형태로 반환
- dict type, keyword parameter 등도 모두 처리 가능
- set 연산들도 지원
#--counter--#
from collections import Counter
stri = 'abcsddsfgdbd'
c = Counter(stri)
print(c)
stri = ['abc', 'vca', 'bsd', 'abc']
c = Counter(stri)
print(c)
c = Counter(a=4, b=3, c=2, d=1, e=0)
print(c) #Counter({'a': 4, 'b': 3, 'c': 2, 'd': 1, 'e': 0})
c.update({'a':3, 'z':10}) #원래 있는거는 더하고 없던거는 추가
print(c) #Counter({'z': 10, 'a': 7, 'b': 3, 'c': 2, 'd': 1, 'e': 0})
d = dict(c) #dict로 변환
print(d) #{'a': 7, 'b': 3, 'c': 2, 'd': 1, 'e': 0, 'z': 10}
#원소 보기
print(list(c.elements())) #['a', 'a' ... 'z', 'z']
#많은 순서대로
print(c.most_common()) #[('z', 10), ('a', 7), ('b', 3), ('c', 2), ('d', 1), ('e', 0)]
print(c.most_common(3)) #3개만 [('z', 10), ('a', 7), ('b', 3)]
#set 연산도 지원
c = Counter(a=4, b=3, c=2, d=1, e=0)
d = Counter(a=1, b=2, c=3, d=4, e=5)
c.subtract(d) #원소별로 빼기
print(c)
c += d
print(c) #원소별로 더하기. 0이 되면 사라지네.
print(c&d) #겹치는 키 중 작은 값 ({'b': 2, 'c': 2, 'a': 1, 'd': 1})
print(c|d) #모든 키 중 큰 값({'e': 5, 'a': 4, 'd': 4, 'b': 3, 'c': 3})
collections.namedtuple
- Tuple 형태로 data 구조체를 저장하는 방법
- 저장되는 데이터 변수를 사전에 지정해서 저장한다.
#--namedtuple--#
from collections import namedtuple
Point = namedtuple('Point', ['x','y'])
p = Point(11, 22)
print(p) #Point(x=11, y=22)
print(p[0]+p[1]) #33
print(Point(11, 22)) #Point(x=11, y=22)
#이렇게 생성 가능
p2 = Point._make([10,20])
print(p2) #Point(x=10, y=20)
#OrderedDict로 변환
print(p2._asdict) #<bound method Point._asdict of Point(x=10, y=20)>
#수정
p2 = p2._replace(x=30)
print(p2) #Point(x=30, y=20)
#필드명 출력
print(p2._fields) #('x', 'y')
#dict to namedtuple
dic = {'x':3, 'y':5}
p3 = Point(**dic)
print(p3) #Point(x=3, y=5)
파이썬 스타일 코드
- 파이썬은 특유의 문법을 활용하여 효율적으로 코드를 표현한다.
*더 이상 파이썬 특유는 아님. 많은 언어들이 서로의 장점을 채용했기 때문.
Split&Join
#--Split&Join--#
stri = "hi my name is lmw"
striSpl = stri.split()
print(striSpl) #['hi', 'my', 'name', 'is', 'lmw']
stri = '-'.join(striSpl)
print(stri) #hi-my-name-is-lmw
List comprehension
- 기존 리스트로 다른 리스트를 만드는 방법
- 포괄적인 리스트, 포함되는 리스트 라는 의미로 사용
- 파이썬에서 많이 사용되고, for+append 보다 빠르다.
#--List Comprehension--#
l = [i for i in range(10)]
print(l)
l = [i for i in range(10) if i%2 == 0] #else도 가능
print(l)
word1 = 'hello'
word2 = 'world'
l = [i+j for i in word1 for j in word2]
print(l)
word1 = ['a','b','c']
word2 = ['d','e','f']
l = [i+j for i in word1 for j in word2]
print(l)
enumerate&zip
- enumerate : list의 원소를 추출할 때 번호를 붙여서 추출
- zip : 두 개의 list 값을 병렬적으로 추출
#--enumerate & zip--#
for i, v in enumerate(['z','s','q']) : print(i, v)
myl = list(enumerate(['z','s','q']))
print(myl) #[(0, 'z'), (1, 's'), (2, 'q')]
word1 = ['a','b','c']
word2 = ['d','e','f']
for a,b in zip(word1, word2) : print(a,b)
a,b,c = zip(word1, word2)
print(a,b,c) #('a', 'd') ('b', 'e') ('c', 'f') 튜플 타입으로 묶어줌
Lambda
- 함수의 이름 없이 함수처럼 쓸 수 있는 익명함수
- 문법, 테스트, 해석이 어려움, 그리고 문서화 docsting 지원이 미비하다.
- Python 3부터는 권장하지 않으나 아직 많이 사용됨 (PEP8도 권장하지 않음)
#--lambda--#
f = lambda x,y : x+y
print(f(1,4))
Map Function
- 두 개 이상의 list에도 적용이 가능하고, if filter도 사용이 가능하다.
- python3는 iteration을 생성하기에 list를 붙여줘야 list 사용이 가능하다.
- 실행시점의 값을 생성해 효율적으로 메모리를 사용한다.
#--map--#
ex = [1,2,3,4,5]
f = lambda x, y: x+y
print(list(map(f,ex,ex))) #[2,4,6,8,10]
print(list(map(lambda x:x**2 if x%2 ==0 else x, ex))) #[1, 4, 3, 16, 5]
Reduce Function
- Map Function과 달리 list에 똑같은 함수를 적용하여 통합한다.
- Map처럼 list로 만드는 것이 아닌, 원소를 하나씩 줄여가며 통합
- Lambda, map, reduce는 간단한 코드로 다양한 기능을 제공한다.
- 하지만 lambda와 마찬가지로 코드의 직관성이 떨어져 권장하지 않는다.
- Legacy Library나 다양한 머신러닝 코드에서는 여전히 사용중.
#--reduce--#
from functools import reduce
print(reduce(lambda x, y: x+y, ex)) #15
Iterable object
- 연속형 자료형에서 데이터를 순서대로 추출하는 객체
- 내부적 구현으로 __iner__와 __next__가 사용됨
- iter()과 next() 함수로 iterable 객체를 iterator object로 사용
#--inerable object--#
cities = ["Seoul", "Busan","Jeju"]
iter_obj = iter(cities)
print(next(iter_obj)) #Seoul
print(next(iter_obj)) #Busan
print(next(iter_obj)) #Jeju
#next(iter_obj) #error
Generator
- iterable object를 특수한 형태로 사용해주는 함수
- element가 사용되는 시점에 값을 메모리에 반환
- yeild를 사용하면 한 번에 하나의 element를 반환
- yield from (리스트명) 을 하면 굳이 포문으로 돌리지 않아도 된다.
- 일반적인 iterator는 generator에 반해 훨씬 큰 메모리 용량을 사용한다.
- list 타입의 데이터를 반환해주는 함수는 generator로 만들면 읽기가 쉽고, 도중에 중단이 가능하다.
- 데이터가 커도 처리의 어려움이 없어 큰 데이터 처리시 사용
- 파일 데이터 처리에도 사용하면 좋다.
#--Generator--#
def general_list(value) :
result = []
for i in range(value) : result.append(i)
return result
print(general_list(5))
#yield를 사용하면 한 번에 하나의 element 반환
def generator_list2(value) :
result = []
for i in range(value) : yield i
a,b,c,d,e = general_list(5)
print(a,b,c,d,e)
Generator Comprehension
- list comprehension과 유사한 형태로 generator 형태의 list 생성
- generator expression이라는 이름으로도 부름
- []대신 ()을 사용해 표현한다.
#--Generator Comprehension--#
gen_ex = (n*n for n in range(10))
print(type(gen_ex))
Iterator와 Generator의 차이점
-Generator는 Iterator를 생성해주는 함수이다.
Iterator란 next()함수를 통해 순차적으로 호출이 가능한 객체인데, generator는 함수 내부에서
yield를 통해 iterator를 생성해주는 함수이다.
Generator가 메모리 측면에서 더 효율적인 이유?
-일반함수의 경우 함수 내부의 구문 실행 후 마지막 return으로 함수가 종료된다.
하지만 generator는 yield를 통해 iterator를 반환하고 그 시점에서 일시정지 후 다음 next 호출을 기다린다.
즉, 필요할 때만 메모리를 반환받아 사용하기에 메모리 측면에서 효율적이다.
데이터가 큰 경우 루프보다 제너레이터를 사용하는 것이 좋다.
Function passing arguments
- 함수에 입력되는 argument는 세 가지 형태가 있다.
1) Keyword argument
- 함수에 입력되는 파라미터의 변수명을 사용해 argument를 넘김
2) Default argument
- 파라미터의 기본 값을 사용해 미입력시 기본값 출력
- default argument는 가능한 뒤로 뺀다.
3) Variable-length argument (가변인자)
-Varuable length (가변인자)
- 함수의 파라미터가 정해지지 않은 경우 사용
- 개수가 정해지지 않은 변수를 함수의 파라미터로 사용하는 법
- Keyword arguments와 함께 argument 추가가 가능하다.
- Asterisk(*) 기호를 사용해 함수의 파라미터를 표시함
- 입력된 값은 tuple type으로 사용할 수 있다.
- 가변인자는 오직 한 개만 맨 마지막 파라미터 위치에 사용가능하다.
- 가변인자는 일반적으로 *args를 변수명으로 사용한다.
- 기존 파라미터 이후에 나오는 값을 튜블로 저장한다.
-Keyword variable-length (키워드 가변인자)
- 파라미터 이름을 따로 지정하지 않고 입력
- Asterisk(*) 두 개를 사용해 함수의 파라미터에 표시 (dict값으로 넘어감)
- 입력된 값은 dict type으로 사용할 수 있다.
- 가변인자는 오직 한 개만 기존 가변인자 다음에 사용한다.
#--Parameter&Argument--#
def print_name(name, age=0) :
print("{}, {}".format(name, age))
print_name(name = 'lmw', age = 27) #KeyWord argument
print_name(name = 'lmw') #Default arhument
#Variable-length asterisk
def print_info(name, age, *etc, **language) :
print('basic info : ', name, age)
print('variable length : ', etc)
print('keyword variable length : ', language)
print('keyword variable length : {language1},{language2},{language3}'.format(**language))
print_info('lmw',27,'경기도','허허',language1 = 'JAVA', language2 = 'Python', language3 = 'JavaScript')
Asterisk (*)
- 단순 곱셈, 제곱연산, 가변인자 활용 등 다양하게 사용된다.
- tuple, dict 등 자료형에 들어간 값을 언패킹할 때 사용
- 함수의 입력값, zip 등에 유용하게 사용가능
#--Asterisk--#
def asterisk_test(a, *args) :
print(a, args, type(args))
#어떻게 넣어도 무조건 튜플로 들어감 : 불변
asterisk_test(1,(1,2,3)) #1 ((1, 2, 3),) <class 'tuple'>
asterisk_test(1,[1,2,3]) #1 ((1, 2, 3),) <class 'tuple'>
asterisk_test(1,{1,2,3}) #1 ((1, 2, 3),) <class 'tuple'>
#자연스럽게 언패킹됨.
data = (1,2,3)
print(*data)
data = ([1,2],[3,4],[5,6])
print(*data)
for d in zip(*data) : print(d)
*오늘의 TIP
-Jupyter Notebook에서 Tab키를 누르면 가용한 함수 리스트가 나옴
- 피어세션 회의 내용
-
- 해야할 일
파이썬에 대한 이해도가 많이 낮았음을 알게해준 강의였다.
아직 모르는 모듈들과 함수, 자료구조들이 많이 존재했고, 이에 대해 각 자료구조의 심화 개념과 응용법을 다져야 할 필요성이 느껴졌다.
참고
excelsior-cjh.tistory.com/98?category=966334
'BOOSTCAMP AI TECH > 1주차_Python Basics For AI' 카테고리의 다른 글
[BOOSTCAMP AI TECH] 5일차_파이썬으로 데이터 다루기 (0) | 2021.01.22 |
---|---|
[BOOSTCAMP AI TECH] 4일차_파이썬 기초문법3 (0) | 2021.01.21 |
[BOOSTCAMP AI TECH] 2일차_파이썬 기초 문법 (0) | 2021.01.19 |
[BOOSTCAMP AI TECH] 1일차_코스 소개 ~ 파이썬 코딩환경 구축 (0) | 2021.01.18 |