Why Pythonic code?
남 코드에 대한 이해도 : 많은 개발자들이 python 스타일로 코딩한다.
효율 : 단순 for loop append 보다 list가 조금 더 빠르다. 익숙해지면 코드가 짧아진다.
Split
type의 값을 "기준값"으로 나눠서 List 형태로 변환
a = " EXTRA SPACE "
b = a.split().lower()
c = a.split(' ')
print(b) # ['EXTRA', 'SPACE']
print(c) # ['', '', '', 'EXTRA', '', '', 'SPACE', '', '', '']
list comprehension
- 기존 List 사용하여 간단히 다른 List를 만드는 기법
- 다른 List를 포함해서 새로운 List를 만드는 것.
- 파이썬에서 가장 많이 사용되는 기법 중 하나
- 일반적으로 for + append 보다 속도가 빠름
result = []
for i in range(10):
result.append(i)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
result = [i for i in range(10)]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
result = [i for i in range(10) if i % 2 == 0]
# [0, 2, 4, 6, 8]
result = [i if i % 2 == 0 else -1 for i in range(10)]
# [0, -1, 2, -1, 4, -1, 6, -1, 8, -1]
word_1 = "Hello"
word_2 = "World"
result = [i + j for i in word_1 for j in word_2]
# ['HW', 'Ho', 'Hr', 'Hl', 'Hd', 'eW', 'eo', 'er', 'el', 'ed', 'lW', 'lo', 'lr', 'll', 'ld', 'lW', 'lo', 'lr', 'll', 'ld', 'oW', 'oo', 'or', 'ol', 'od']
case_1 = ["a","b","c"]
case_2 = ["d","e","a"]
result = [i+j for i in case_1 for j in case_2] # case_1부터
# ['ad', 'ae', 'aa', 'bd', 'be', 'ba', 'cd', 'ce', 'ca']
result = [[i+j for i in case_1] for j in case_2] # case_2부터
# [['ad', 'bd', 'cd'], ['ae', 'be', 'ce'], ['aa', 'ba', 'ca']]
result = []
for i in range(10):
result.append(i)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
result = [i for i in range(10)]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
result = [i for i in range(10) if i % 2 == 0]
# [0, 2, 4, 6, 8]
result = [i if i % 2 == 0 else -1 for i in range(10)]
# [0, -1, 2, -1, 4, -1, 6, -1, 8, -1]
word_1 = "Hello"
word_2 = "World"
result = [i + j for i in word_1 for j in word_2]
# ['HW', 'Ho', 'Hr', 'Hl', 'Hd', 'eW', 'eo', 'er', 'el', 'ed', 'lW', 'lo', 'lr', 'll', 'ld', 'lW', 'lo', 'lr', 'll', 'ld', 'oW', 'oo', 'or', 'ol', 'od']
case_1 = ["a","b","c"]
case_2 = ["d","e","a"]
result = [i+j for i in case_1 for j in case_2] # case_1부터
# ['ad', 'ae', 'aa', 'bd', 'be', 'ba', 'cd', 'ce', 'ca']
result = [[i+j for i in case_1] for j in case_2] # case_2부터
# [['ad', 'bd', 'cd'], ['ae', 'be', 'ce'], ['aa', 'ba', 'ca']]
여담으로 pprint.pprint를 쓰면 이쁘게 나온다!
enumerate & zip
enumerate : list의 element를 추출할 때 번호를 붙여서 추출
- 나오는 형태는 Tuple
for i, v in enumerate('abc'):
print("{0} {1}".format(i,v))
# 0 a
# 1 b
# 2 c
for i, v in enumerate(['a','b','c']):
print("{0} {1}".format(i,v))
# 0 a
# 1 b
# 2 c
zip : 두 개의 list의 값을 병렬적으로 추출함
alist = ['a1','a2','a3']
blist = ['b1','b2','b3']
[[a,b] for a, b in zip(alist, blist)]
# [['a1', 'b1'], ['a2', 'b2'], ['a3', 'b3']]
[c for c in zip(alist, blist)]
# [c for c in zip(alist, blist)]
list(enumerate(zip(alist, blist)))
# [(0, ('a1', 'b1')), (1, ('a2', 'b2')), (2, ('a3', 'b3'))]
lambda & map & reduce
lambda
함수 이름 없이, 함수처럼 쓸 수 있는 익명함수
수학의 람다 대수에서 유래함
def f(x, y):
return x + y
f = lambda x, y : x + y
PEP 8에서는 lambda의 사용을 권장하지 않음
- 어려운 문법
- 테스트의 어려움
- 문서화 docstring 지원 미비
- 코드 해석의 어려움
- 이름이 존재하지 않는 함수의 출현
- 그래도 쓰는..
Map
두 개 이상의 list에도 적용 가능함, if filter도 사용가능
굳이 map을 사용하기 보다는 list comprehension을 사용하도록
ex = [1,2,3,4,5]
f = lambda x: x ** 2
list(map(f, ex))
# [1, 4, 9, 16, 25]
[f(value) for value in ex]
reduce
map function과 달리 list에 똑같은 함수를 적용해서 통합
대용량 데이터를 핸들링할 때, 주로 사용.
from functools import reduce
ex = [1,2,3,4,5]
f = lambda x, y: x + y
print(reduce(f,ex))
# 15
generator
Iterable data
- Sequence형 자료형에서 데이터를 순서대로 추출하는 object
- 내용이 아닌 위치정보(주소값)에 대한 정보가 저장됨.
- next를 하면 다음 메모리 주소에 있는 값을 불러옴.
- cities_주소 → seoul_주소 → busan_주소 → jeju_주소 → 없으므로 에러
cities = ["seoul", "busan", "jeju"]
memory_address = iter(cities)
# <list_iterator at 0x1ec8cbc6788>
next(memory_address) # seoul
next(memory_address) # busan
next(memory_address) # jeju
generator
- iterable object를 특수한 형태로 사용해주는 함수
- element가 사용되는 시점에 값을 메모리에 반환
- yield를 사용해 한번에 하나의 element만 반환함.
- 용량을 줄일 수 있기 때문에 대용량인 경우 사용하는 것이 효율적임.
import sys
def general_list(value):
result = []
for i in range(value):
result.append(i)
return result
result = general_list(50)
sys.getsizeof(result)
# 528
import sys
def generator_list(value):
result = []
for i in range(value):
yield i
result = generator_list(50)
sys.getsizeof(result)
# 120
sys.getsizeof(list(generator_list(50)
# 472
When generator
- list 타입의 데이터를 반환해주는 함수는 generator로!
→ 특히 사용하면 읽기 쉽고, 중간 과정에서 loop가 중단될 수 있을때
- 큰 데이터를 처리할 때는 generator expression을 고려
→ 데이터가 커도 처리의 어려움이 없음.
- 파일 데이터를 처리할 때도 generator를 사용하자
asterisk
함수에 입력되는 parameter의 변수명을 사용하여 argument를 넘김.
# Keyword arguments
def print_name_keyword(name, you_name):
print("Hello {}, my name is {}".format(you_name, name))
print_name_keyword(name="aaa",you_name="bbb")
# default arguments
def print_name_default(name, you_name="NAVER"):
print("Hello {}, my name is {}".format(you_name, name))
print_name_default("hwan")
# Hello NAVER, my name is hwan
print_name_default("hwan", "AA")
# Hello AA, my name is hwan
가변인자(variable-length)
- 개수가 정해지지 않은 변수를 함수의 parameter로 사용하는 법
- Keyword arguments와 함계, argument 추가가 가능
- Asterisk(*) 기호를 사용하여 함수의 parameter를 표시함
- 입력된 값은 tuple type으로 사용할 수 있음
- 가변인자는 오직 한 개만 맨 마지막 parameter 위치에 사용가능
def asterisk_test(a, b, *args):
print(a)
print(b)
print(args)
print(type(args))
asterisk_test(1,2,3,4,5)
# 1
# 2
# (3, 4, 5)
# <class 'tuple'>
키워드 가변인자(Keyword variable-length)
- Parameter 이름을 따로 지정하지 않고 입력하는 방법
- asterisk(*) 두개를 사용하여 함수의 parameter를 표시함
- 입력된 값은 dict type으로 사용할 수 있음
- 가변인자는 오직 한 개만 기존 가변인자 다음에 사용
def kwargs_test(**kwargs):
print(kwargs)
print(type(kwargs))
kwargs_test(first=3, second=4, third=5)
# {'first': 3, 'second': 4, 'third': 5}
# <class 'dict'>
결론으로는 argument는 그냥 파라미터, 키워드 파라미터, 가변인자, 키워드 가변인자 순으로 작성해야함.
def test_3(one, two=3, *args, **kwargs):
print(one,two, args, kwargs)
test_3(1,2,3,4,5,6,6,a=100,b=200)
# 1 2 (3, 4, 5, 6, 6) {'a': 100, 'b': 200}
asterisk(*)
- 흔히 알고 있는 *를 의미함.
- tuple, dict 등 자료형에 들어가 있는 값을 unpacking
- 함수의 입력값, zip 등에 유용하게 사용가능
def asterisk_test(a, *args):
print(a, args)
print(type(args))
def asterisk_test2(a, args):
print(a, *args)
print(type(args))
asterisk_test(1,*(2,3,4,5,6)) # (1,2,3,4,5,6)과 같음
# 1 (2, 3, 4, 5, 6)
# <class 'tuple'>
asterisk_test(1,(2,3,4,5,6))
# 1 2 3 4 5 6
# <class 'tuple'>
data = ([1,2,],[3,4,],[5,6,])
print(*data)
# [1, 2] [3, 4] [5, 6]
for i in zip(*data):
print(i)
# (1, 3, 5)
# (2, 4, 6)
def asterisk_test(a,b,c,d):
print(a,b,c,d)
data = {"b":1,"c":2,"d":3}
asterisk_test(10, **data)
# 10 1 2 3
'인공지능 공부 > 이론 및 파이썬' 카테고리의 다른 글
[이론 및 파이썬] 언더스코어/언더바(_)의 역할 (0) | 2021.01.24 |
---|---|
[이론 및 파이썬] 파이썬 숫자판별 함수 정리 (0) | 2021.01.24 |
[이론 및 파이썬] Python Object-Oriented Programming (0) | 2021.01.22 |
[이론 및 파이썬] Python이 무엇인가? (0) | 2021.01.18 |
[이론 및 파이썬] OS와 CLI (0) | 2021.01.18 |