해당 포스팅은 네이버 부스트캠프 AI Tech 학습 정리 자료임을 알려드립니다.
1. 강의 정리
최성철 교수님 - Python Data Structure
1) 스택과 큐(stack & queue with list)
스택(stack)은 나중에 넣은 데이터를 먼저 반환하도록 설계된 메모리 구조입니다. 흔히 Last In First Out(LIFO)라고 합니다. 파이썬에서는 스택을 리스트로 구현할 수 있습니다. push는 append() 명령어로, pop은 pop() 명령어를 사용합니다.
큐(Queue)는 먼저 넣은 데이터를 먼저 반환하도록 설계된 메모리 구조입니다. 흔히 First In First Out(FIFO)라고 합니다. 큐도 마찬가지로 리스트를 활용해서 구현할 수 있습니다. put은 append() 명령어로, get은 pop(0) 명령어를 사용합니다. deque라는 collections 패키지를 활용해서 구현도 가능합니다.
2) 튜플과 집합(tuple & set)
튜플(tuple)은 값의 변경이 불가능한 리스트 형태입니다. 선언 시에는 "[]" 대신 "()"를 사용합니다. 튜플은 리스트와 마찬가지로 연산, 인덱싱, 슬라이싱 등의 기능을 사용할 수 있습니다. 그러면 리스트를 활용하는 게 더 좋지 않을까라는 생각을 할 수 있습니다. 그래서 튜플은 값을 변경할 수 없다는 것을 활용해서 프로그램 작동하는 동안 변경되지 않는 데이터를 저장하는 데 활용됩니다. 예를 들어, 학번이나 이름과 같이 변하지 않는 데이터에서 활용됩니다.
집합(set)은 값을 순서없이 저장하거나 중복하여 저장하는 것을 막는 자료형입니다. 수학에서 사용했던 집합의 개념을 구현한 것이라고 생각하시면 됩니다. 그래서 set 객체는 합집합(union), 교집합(intersection), 차집합(difference)과 같은 연산이 가능하도록 구현되어 있습니다.
3) 사전(dictionary)
사전(dictionary)는 데이터를 저장할 때 구분 지을 수 있는 값을 함께 저장하는 형태입니다. 다른 구조와는 다르게 key, value로 구성되어 있습니다. 다른 언어에서는 사전과 같은 형태를 해쉬 테이블이라고 부릅니다. 사전은 보통 "{}" 또는 "dict()"로 선언할 수 있습니다. 주로 사용되는 명령어로는 "items() : Dict 데이터 출력", "keys() : Dict 키 값만 출력", "values() : Dict Value만 출력" 등이 있습니다.
4) Collections 모듈
collections 모듈은 List, Tuple, Dict에 대한 Python Built-in 확장 자료 구조입니다. 편의성과 실행 효율을 사용자에게 제공합니다. 모듈에는 deque, Counter, OrderedDict, defaultdict, namedtuple 이 있습니다.
deque는 Stack과 Queue 를 지원하는 모듈입니다. list보다 빠르고 효율적인 저장 방식을 지원합니다. rotate, reverse 등과 같이 Linked List(연결 리스트)의 특성을 지원합니다.
OrderedDict는 일반적인 Dict와는 다르게 데이터를 입력한 순서대로 dict를 반환합니다. 하지만, python 3.6부터는 입력한 순서를 보장하여 출력합니다. Dict type의 값을 value 또는 key 값으로 정렬할 때 사용 가능합니다.
defaultdict는 Dict type의 값에 기본 값을 지정하고 신규 값 생성 시에 사용하는 방법입니다. 함수를 통해서 Default 값을 지정해줄 수 있습니다. 주로, 단어를 카운팅 할 때 활용이 됩니다.
Counter는 시퀀스 형태의 데이터 요소들의 갯수를 dict 형태로 반환해주는 방법입니다. Dict type, keyword parameter 등 모두 처리가 가능하고, set의 연산들도 지원합니다. word counter의 기능도 손쉽게 제공하고 있습니다.
namedtuple은 tuple 형태로 Data 구조체를 저장하는 방법입니다. 저장되는 data의 변수들을 사전에 지정해서 저장합니다. 지정한 이름을 class형태로 활용이 가능합니다.
최성철 교수님 - Pythonic code
1) Pythonic code
Pythonic code에 포함되는 내용은 split&join, list comprehension, enumerate&zip, lambda&map&reduce, generator, asterisk 등이 있습니다. 파이썬 스타일의 코드를 사용하는 이유는 다른 개발자들의 파이썬 스타일 코드를 이해하는데 도움이 되며 코드도 짧아지고 효율이 증가합니다.
2) Split & join
split()은 ()안에 있는 기준값으로 나눠서 list 형태로 변환해주는 함수입니다. 문자열도 list 형태로 반환하기도 하고, list를 unpacking 하기도 합니다. join()은 string으로 구성된 list를 합쳐서 하나의 string으로 반환하는 함수입니다.
3) list comprehension
list comprehension은 기존 list를 사용해서 간단하게 다른 list를 만드는 기법입니다. 파이썬에서 가장 많이 사용되는 기법 중에 하나이며, for + append 보다 속도가 빠릅니다. 미세하게 빠른 이유는 파이썬이 인터프리터 언어여서 1줄씩 기계어로 바꾸는 과정을 거치기 때문입니다.
[i+j for i in A for j in B] # A가 포함된 for문이 먼저 실행, 그 다음엔 B가 포함된 for문이 실행
[i+j for i in case_1 for j in case_2 if not(i==j)] # if 이하는 filter의 역할
[i+j if not(i==j) else i for i in case_1 for j in case_2] #if else 형태로도 가능
4) enumerate & zip
enumerate는 list의 요소들을 추출할 때 번호(index)를 붙여서 추출합니다. zip은 두 개의 list의 값을 병렬적으로 추출합니다. 같은 index를 가지고 있는 값들을 뽑아내고 싶을 때, 활용할 수 있습니다.
5) lambda & map & reduce
lambda는 함수 이름 없이, 함수처럼 사용할 수 있는 익명함수입니다. PEP 8에서 lambda의 사용을 권장하지 않지만 여전히 많이 사용되고 있습니다. lambda의 문제점으로는 문법이 어렵고, 함수가 잘 돌아가는지 테스트하기 어렵습니다. docstring 지원이 미비하며 코드 해석이 어렵다는 문제들이 존재합니다.
map은 함수를 리스트에 동시에 원소별로 적용할 때 사용합니다. 실행시점에 값을 생성하므로, 메모리 측면에서 효율적입니다.
reduce는 map function과 달리 list에 똑같은 함수를 적용해서 원소를 통합하는 함수입니다. functools라는 패키지에 포함되어 있습니다.
lambda, map, reduce는 간단한 코드로 다양한 기능을 제공하지만 직관성이 떨어져서 사용을 권장하지는 않습니다. 하지만, 여전히 많이 사용되고 있는 함수입니다.
6) iterable object
iterable object는 Sequence 자료형에서 데이터를 순서대로 추출하는 object입니다. 내부적으로 __iter__와 __next__가 사용됩니다.
cities = ["Seoul", "Busan", "Jeju"]
iter_obj = iter(cities)
print(next(iter_obj)) # "Seoul"
print(next(iter_obj)) # "Busan"
print(next(iter_obj)) # "Jeju"
7) generator
generator는 iterable object를 특수한 형태로 사용해주는 함수입니다. element가 사용되는 시점에 값을 메모리에 반환해주는 형태입니다. yield를 사용해서 한 번에 하나의 element만 반환합니다. 아래와 같이 generator expression은 ()를 활용해서 표현합니다. 일반적인 iterator는 generator보다 많은 메모리를 사용합니다.
gen = (n*n for n in range(500))
generator는 list 타입의 데이터를 반환해주는 함수에 사용하면 좋습니다. 큰 데이터를 처리할 때는 generator expression을 사용하면 데이터가 아무리 커도 어려움이 없습니다. 파일 데이터를 처리할 때도 generator를 사용하면 좋습니다.
8) function passing arguments & asterisk
함수에 입력되는 arguments는 다양한 형태를 가지고 있습니다. Keyword arguments, Default arguments, Variable-length arguments 등이 존재합니다.
Keyword arguments는 함수에 입력되는 parameter의 변수명을 사용하는 특징이 있습니다. Default arguments는 parameter의 기본 값을 사용합니다. 만약, 입력하지 않으면 기본값을 출력합니다. variable-length asterisk는 함수의 parameter가 정해져 있지 않을 때 활용합니다.
variable-length는 개수가 정해지지 않은 변수를 함수의 parameter로 사용하는 방법입니다. Keyword arguments와 함께 argument 추가가 가능하고, Asterisk(*) 기호를 사용해서 함수의 parameter를 표시합니다. 입력된 값은 tuple type으로 사용할 수 있습니다. 가변 인자는 오직 한 개만 맨 마지막 parameter 위치에 사용이 가능합니다. 일반적으로 함수에 사용될 때, *args로 사용됩니다.
keyword variable-length라는 것이 있는데 *args에서는 튜플을 사용했다면, **kwargs로 dict형을 사용할 수 있습니다. 아래 예시를 보면 쉽게 이해할 수 있습니다.
def kwargs_test(one, two, *args, **kwargs):
print(one+two+sum(args)) # 3+4+5+6+7+8+9
print(kwargs) # {'first': 3, 'second': 4, 'third': 5}
kwargs_test(3,4,5,6,7,8,9, first=3, second=4, third=5)
# one = 3, two = 4로 넣은 다음에 5~9는 args로 입력되고, first=3, second=4, third=5는 kwargs로 들어가게 됩니다.
asterisk는 다양하게 사용되는 데, 단순 연산의 곱셈, 제곱연산, 가변 인자 활용, unpacking에도 사용됩니다. tuple이나 dict 등 자료형에 들어가 있는 값을 unpacking 할 때, *를 앞에 붙여주면 unpacking이 됩니다. tuple은 *한 개, dict는 **두 개를 사용합니다.
2. 피어 세션 정리
숙제 검사, 숙제 제출방법, 학습 내용에 대한 질문, 조교님 첫 미팅, slack 활용
3. 과제 진행 상황
완료 : text_processing 2, baseball