===================================
수업내용
Python Data Structure
- 스택과 큐 (stack & queue with list)
- 튜플과 집합(tuple & set)
- 사전(dictionary)
- Collection 모듈
Stack
Last In First Out (LIFO)
push, pop
a.append(10)
a.pop()
Queue
First In First Out (FIFO)
a.append(10)
a.pop()
tuple
값의 변경이 불가능한 리스트
[] 대신 () 사용
하나일 경우 t = (1,) 로 해야 튜플로 인식
집합 (set)
값을 순서업싱 저장, 중복을 불허하는 자료형
s = set([1,2,3,1,2,3])
s # {1,2,3}
s. add(5)
s.remove(2)
s.update([1,4,5,6,7])
s1.union(s2) 또는 s1 | s2 # 합집합
s1.intersection(s2) 또는 s1 & s2 # 교집합
s1.difference(s2) 또는 s1 - s2 # s1과 s2의 차집합
사전 (dictionary)
Key 값을 활용하여 Value를 관리함
Collections 모듈
from collections import deque
from collections import Counter
from collections import OrderedDict
from collections import defaultdict
from collections import namedtuple
deque
rotate, extend, extendleft(거꾸로 붙음) 함수도 있다
기존 list보다 효율적인 자료구조를 제공
효율적 메모리 구조로 처리속도 향상
OrderedDict
근데 python 3.6부터 일단 dict도 입력한 순서를 보장하여 출력함
defaultdict
신규값을 안넣어도 알아서.
Dict type의 값에 기본 값(초기 값)을 지정, 신규값 생성시 사용하는 방법
from collections import defaultdict
d = defaultdict(object) # default dictionary를 생성
d = defaultdict(lambda: 0) # default 값을 0으로 설정함. 함수 형태로 넣어줘야 함.
print(d["first"])
Counter
Sequence type의 data element들의 갯수를 dict 형태로 변환
c = Counter(a=4, b=2, c=0, d=-2)
d = Counter(a=1, b=2, c=3, d=4)
c.subtract(d) # Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
Set의 연산들을 지원함. c+d, c&d, c|d
namedtuple
Tuple 형태로 Data 구조체를 저장하는 방법
저장되는 data의 variable을 사전에 지정해서 저장함
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(11, y=22)
print(p[0] + p[1])
x, y = p
print(x, y)
print(p.x + p.y)
print(Point(x=11, y=22))
Pythonic code
예)
colors = ['red', blue', 'yellow']
''.join(colors)
- split & join
- list comprehension
- enumerate & zip
- lambda & map & reduce
- generator
- asterisk
split & join
a.split(), a.split(',')
''.join(a), '-'.join(a)
list comprehension
result = [i for i in range(10) if i % 2 == 0]
word_1 = "Hello"
word_2 = "World"
result = [i+j for i in word_1 for jj in word_2] #Nested For loop
result # ['HW', 'Ho', 'Hr', 'Hl', 'Hd', 'eW', 'eo', ... ,'od']
for i in word_1:
for j in world_2:
result.append(i+j)
result = [i+j for i in case_1 for j in case_2 if not(i==j)] # filter
result = [i+j if not(i==j) else i for i in case_1 for j in case_2] # 도 가능
stuff = [[w.upper(), w.lower(), len(w)] for w in words]
하면 2차원으로 나옴
Two dimensional vs One dimensional
case_1 = ["A", "B", "C"]
case_2 = ["D", "E", "A"]
result = [i+j for i in case_1 for j in case_2]
['AD', 'AE', 'AA', 'BD', 'BE', 'BA', 'CD', 'CE', 'CA']
for i in case_1:
for j in case_2:
result.append(i+j)
result = [ [ i+j for i in case_1 ] for j in case_2 ]
[ [ 'AD', 'BD' 'CD' ], [ 'AE', 'BE', 'CE' ], [ 'AA', 'BA', 'CA' ] ]
for j in case_2:
line = [ ]
for i in case_1:
line.append(i+j)
result.append(line)
result = [ [ i+j for i in case_1 if i != 'C' ] for j in case_2 ]
enumerate & zip
for i, v in enumerate(['tic', 'tac', 'toe']):
print(i, v)
my_str = 'ABCD'
{v : i for i, v in enumerate(my_str)}
{ 'A': 0, 'B': 1, 'C': 2, 'D': 3 }
alist = ['a1', 'a2', 'a3']
blist = ['b1', 'b2', 'b3']
for a, b in zip(alist, blist):
print(a, b)
math = (100, 90, 80)
kor = (90, 90, 70)
eng = (90, 80, 70)
[ sum(value) / 3 for value in zip(math, kor, eng) ]
lambda & map & reduce
f = (lambda x, y : x + y)
f(10, 50)
(lambda x, y : x + y)(10, 50)
python 3 부터는 권장하지 않으나 많이 쓰임
def f(x): return 2*x # YES
f = lambda x: 2*x # NO
ex = [ 1, 2, 3, 4, 5]
f = lambda x: x ** 2
list(map(f, ex)) # [1,4,9,16,25]
f = lambda x, y : x + y
list(map(f, ex, ex)) # [2, 4, 6, 8, 10]
근데 복잡하니까 차라리
[ f(value) for value in ex ] 로 써라
list(map(lambda x : x ** 2 if x % 2 == 0 else x, ex)) 대신
[ value**2 if value % 2 == 0 else value for value in ex ]
from functools import reduce
map function과 달리 list에 똑같은 함수를 적용해서 통합
print( reduct( lambda x, y : x+y, [ 1, 2, 3, 4, 5 ])) # 15
iterable object (for learn Generator)
차례대로 출력하는 모든 object가 iterable object
내부적 구현으로 __iter__와 __next__ 가 사용됨
iter() 와 next() 함수로 iterable 객체를 iterator object로 사용
cities = [ "Seoul", "Busan", "Jeju" ]
memory_address_cities = iter(cities)
print(next(memory_address_cities ))
print(next(memory_address_cities ))
print(next(memory_address_cities ))
next(memory_address_cities )
시작 메모리 값을 저장
for city in cities:
print(city)
할 때 사실 내부적으로 사용되고 있었다.
Generator
iterable object를 특수한 형태로 사용해주는 함수
element가 사용되는 시점에 값을 메모리에 반환
: yield를 사용해 한번에 하나의 element만 반환함
메모리 주소만 가지고 있다
for e in list(range(50)):
print(e)
sys.getsizeof(list(range(50)) # 520
def generator_list(num):
for i in range(num):
yield i
for e in generator_list(50):
print(e)
sys.getsizeof(generator_list(50)) # 120
generator comprehension
list comprehension과 유사한 형태로 generator형태의 list 생성
generator experssion 이라는 이름으로도 부름
[ ] 대신 ( ) 를 사용하여 표현
gen_ex = ( n*n for n in range(500) )
print(type(g))
for 나 list를 써주면 메모리에 올라감
일반적인 iterator는 generator에 반해 훨씬 큰 메모리 용량 사용
gen_ex = ( n*n for n in range(50000) )
getsizeof(gen_ex)) # 112
getsizeof(list(gen)ex)) # 40808
list_ex = [ n*n for n in range(50000) ]
getsizeof(list_ex) # 43032
- list 타입의 데이터를 반환해주는 함수는 generator로 만들어라!
: 읽기 쉬운 장점, 중간 과정에서 loop이 중단될 수 있을 때
- 큰 데이터를 처리할 때는 generator expression을 고려하라!
: 데이터가 커도 처리의 어려움이 없음
- 파일 데이터를 처리할 때도 generator를 쓰자
function passing arguments
- 함수에 입력되는 arguments의 다양한 형태
1) Keyword argument
2) Default argument
3) Variable-length arguments
Keyword argument
def print_something(my_name, your_name):
print("Hello {0}, My name is {1}".format(yourname, my_name))
print_something("gun", "teamlab")
print_something(your_name = "teamlab", "gun")
Default argument
def print_something(my_name, your_name="teamlab"):
print("Hello {0}, My name is {1}".format(yourname, my_name))
print_something("gun", "teamlab")
print_something("gun")
Variable-length argument
가변인자 (variable-length)
- 개수가 정해지지 않은 변수를 함수의 parameter로 사용하는 법
- Keyword arguments와 함께, argument 추가가 가능
- Asterisk(*) 기호를 사용하여 함수의 parameter를 푝시함
- 입력된 값은 tuple type으로 사용할 수 있음
- 가변인자는 오직 한 개만 맨 마지막 parameter 위치에 사용가능
- 가변인자는 일반적으로 *args를 변수명으로 사용
- 기존 parameter 이후에 나오는 값을 tuple로 저장함
키워드 가변인자 (Keyword variable-length)
- Parameter 이름을 따로 지정하지 않고 입력하는 방법
- asterisk(*) 두개를 사용하여 함수의 parameter를 표시함
- 입력된 값은 dict type으로 사용할 수 있음
- 가변인자는 오직 한 개만 기존 가변인자 다음에 사용
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'>
def asterisk_test(a, **kwargs):
print(a, kwargs)
print(type(kwargs))
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'>
def kwargs_test_3(one, two=3, *args, **kwargs):
print(one)
print(two)
print(args)
print(kwargs)
kwargs_test_3( 10, 30, 3, 5, 6, 7, 8, first=3, second=4, third=5 )
# 변수 넣는 순서 지켜야 한다. 키워드는 뒤에 넣어야 함.
10
30
(3, 5, 6, 7, 8)
{'first': 3, 'second': 4, 'third': 5}
asterisk
- 흔히 알고 있는 *를 의미함
- 단순 곱셈, 제곱연산, 가변 인자 활용 등 다양하게 사용됨
- tuple, dict 등 자료형에 들어가 있는 값을 unpacking
- 함수의 입력값, zip 등에 유용하게 사용가능
함수에 넣는 *args나 **kwargs 와는 다른 *다. 헷갈리지 말기.
def asterisk_test_1(a, *args):
print(a, *args)
print(a, args) # 변수를 딱 하나로만 해서 tuple 값으로 들어감
print(type(args))
test = ( 2 ,3 ,4 ,5 ,6 )
asterisk_test_1(1, *test) 은 asterisk_test_1(1, 2, 3, 4, 5, 6) 과 같음
# 1 2 3 4 5 6
# 1 (2, 3, 4, 5, 6)
# <class 'tuple'>
def asterisk_test_2(a, *args):
print(a, *args)
print(a, args)
print(type(args))
test = ( 2, 3, 4, 5, 6 )
asterisk_test_2(1, test)
# 1 (2 3 4 5 6)
# 1 ((2, 3, 4, 5, 6),)
# <class 'tuple'>
def asterisk_test_3(a,b,c,d):
print(a,b,c,d)
data = {"b":1, "c":2, "d":3}
asterisk_test(10,**data) # **data하면 dict 풀어서 b=1, c=2, d=3이 그대로 들어감
# 10 1 2 3
print(*data)
# b c d
# print(**data) # 에러뜸
ex = ([1,2],[3,4],[5,6])
print(ex) # ([1,2],[3,4],[5,6])
print(*ex) # [1,2] [3,4] [5,6]
for i in zip(*ex):
print(i)
(1,3,5)
(2,4,6)
은
for i in zip([1,2],[3,4],[5,6]):
print(i)
과 같음.
===================================
피어세션
이번에 파이썬에서만 있는 문법들이 많았기 때문에 다른언어와의 차이점 및 리트코드에서 풀었던 각자의 방식을 공유하는 시간을 가졌다.
또 취업에 대한 궁금증, 다른 기업들은 어떤 인재를 선호하는지, 어떤식으로 취업시장이 돌아가는지에 대한 얘기를 나눴다. 눈이 넓어진 느낌이다.
===================================
오늘 공부 후기
진짜 comprehension 이나 asterisk는 검색해도 찔끔찔끔 나오거나 찾기 힘든 내용인데 이런걸 한번에 알려줘서 정말 유익하고 감사했다. 또 피어세션에서 다른 피어분들의 말을 듣고 작기만 했던 견문을 넓힌 느낌이라 정말 좋았다.
특히 Generator, 가변인자, asterisk는 꼭 기억하자
'과거의 것들 > AI Tech boostcamp' 카테고리의 다른 글
AITech 학습정리-[DAY 6] Numpy / 벡터 / 행렬 (0) | 2021.11.26 |
---|---|
AITech 학습정리-[DAY 5] 파이썬으로 데이터 다루기 (0) | 2021.11.26 |
AITech 학습정리-[DAY 2] 파이썬 기초 문법 (0) | 2021.11.26 |
AITech 학습정리-[DAY 1] 파이썬/AI 개발환경 준비하기 (0) | 2021.11.26 |
앞으로 올리는거는 과거의 것을 복사하는 것임 (0) | 2021.11.26 |