Pythonic Code(복습용)
Overview
- 파이썬 스타일의 코딩 기법
- 파이썬 특유의 문법을 활용하여 효율적으로 코드를 표현함
- 고급 코드를 작성 할 수록 더 많이 필요해짐
Example code
colors = ['red', 'blue', 'green', 'yellow']
result = ''
for s in colors:
result += s
print(result)
# 'redbluegreenyellow'
result = ''.()
print(result)
# 'redbluegreenyellow'
Contents
- split & join
- list comprehension
- enumerate & zip
- lambda & map & reduce
- generator
- asterisk
and
split
string type의 값을 '기준값'으로 나눠서 List 형태로 변환
items = 'zero one two three'. # 스페이스를 기준으로 문자열 나누기
# ['zero', 'one', 'two', 'three']
example = "teamlab.technology.io"
subdomain, domain, tld = example.
join
colors = ["red", "blue", "green", "yellow"]
<input type="text" data-answer=""_".join" />(colors)
# 'red-blue-green-yellow'
기존 List를 사용하여 간단히 다른 List를 만드는 방법
일반적으로 for + append보다 속도가 빠름
# General Style
result = []
for i in range(10):
result.append(i)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# List comprehension
result = [i for i in range(10)]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
result = [] # Filter
# [0, 2, 4, 6, 8]
word_1 = "Hello"
word_2 = "World"
result = [i+j for i in word_1 for j in word_2] # Nested for loop
# ['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']
result = [i+j for i in word_1 for j in word_2 if not(i==j)]
result = [i+j if not(i==j) else i for i in word_1 for j in word_2]
import pprint
words = 'The quick brown fox jumps over the lazy dog'.split()
stuff = [[w.(), w.(), (w)] for w in words]
pprint.pprint(stuff)
"""
[['THE', 'the', 3],
['QUICK', 'quick', 5],
['BROWN', 'brown', 5],
['FOX', 'fox', 3],
['JUMPS', 'jumps', 5],
['OVER', 'over', 4],
['THE', 'the', 3],
['LAZY', 'lazy', 4],
['DOG', 'dog', 3]]
"""
Two dimensional vs One dimensional
case_1 = ["A", "B", "C"]
case_2 = ["D", "E", "F"]
result = [[i+j for i in case_1] for j in case_2]
# [['AD', 'BD', 'CD'], ['AE', 'BE', 'CE'], ['AA', 'BA', 'CA']]
&
enumerate
enumerate : 와 함께 list의 를 추출
# dict 타입으로 만들 때 자주 사용
text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
{v.lower() : i for i, v in }
"""
{'adipiscing': 6,
'aliqua.': 18,
'amet,': 4,
'consectetur': 5,
'do': 9,
'dolor': 2,
'dolore': 16,
'eiusmod': 10,
'elit,': 7,
'et': 15,
'incididunt': 12,
'ipsum': 1,
'labore': 14,
'lorem': 0,
'magna': 17,
'sed': 8,
'sit': 3,
'tempor': 11,
'ut': 13}
"""
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']]
& &
함수 이름 없이 쓸 수 있는 익명함수
수학의 람다 대수에서 유래함
# general function
def f(x, y):
return x + y
# lambda function
f =
(lambda x, y: x+y)(10, 50)
권장: def f(x): return 2*x
PEP 8에서는 lambda의 사용을 권장하지 않음:
- 어려운 문법
- 테스트의 어려움
- 문서화 docstring 지원 미비
주어진 함수를 시퀀스의 각 요소에 적용하여 새로운 시퀀스를 반환하는 함수
두 개 이상의 list에도 적용 가능함, if filter도 사용가능
list comprehension을 사용하는 걸 권장하는 분위기
ex = [1, 2, 3, 4, 5]
f = lambda x,y: x+y
list(map(f, ex, ex))
[f(value, value) for value in ex]
map function과 달리 list에 똑같은 함수를 적용해서 통합
대용량의 데이터를 다룰 때 사용
import reduce
print(reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]))
# 15
object
Sequence형 자료형에서 데이터를 순서대로 추출하는 object
내부적으로 iter와 next가 사용됨
iter()와 next() 함수로 iterable 객체를 iterator object로 사용
cities = ["Seoul", "Busan", "Jeju"]
iter_obj = (cities)
print(next(iter_obj))
print(next(iter_obj))
print(next(iter_obj))
iterable object를 특수한 형태로 사용해주는 함수
element가 사용되는 시점에 값을 메모리에 반환
yield를 사용해 한번에 하나의 element만 반환함
장점
- 메모리 효율성: 한 번에 하나의 요소만 메모리에 올리므로 큰 데이터를 처리할 때 유리합니다.
- 느긋한 계산: 필요할 때마다 값을 생성하여 불필요한 계산을 피할 수 있습니다.
- 성능 최적화: 함수의 상태를 유지하며 효율적인 반복 작업을 수행할 수 있습니다.
- 코드의 간결함: 복잡한 이터레이션 로직을 간단하게 작성할 수 있습니다.
Why & When
- 일반적인 iterator는 generator에 반해 훨씬 큰 메모리 용량 사용
- list 타입의 데이터를 반환해주는 함수는 generator로 만들어라
- 큰 데이터를 처리할 때는 generator expression을 고려하라
- 파일 데이터를 처리할 때도 generator를 쓰자
def simple_generator():
for i in range(1, 11):
i
# 제너레이터 객체 생성
gen = simple_generator()
# 제너레이터에서 값을 하나씩 꺼내기
for value in gen:
print(value)
generator comprehension
list comprehension과 유사한 형태로 generator형태의 list 생성
generator expression이라는 이름으로도 부름
[] 대신 를 사용하여 표현
gen_ex = (n*n for n in range(500))
function passing arguments
함수에 입력되는 arguments의 다양한 형태
- Keyword arguments
- Default arguments
- Variable-length asterisk
1. Keyword arguments
함수에 입력되는 parameter의 을 사용, arguments를 넘김
def print_something(my_name, your_name):
print(f"{my_name} {your_name}")
print_something(your_name = "aa", my_name = "bb") # your_name, my_name과 같이 parameter의 변수명을 사용하는 것을 Keyword arguments
2. arguments
parameter의 을 사용, 입력하지 않을 경우 출력
def print_something(my_name, your_name = "aa"):
print(f"{my_name} {your_name}")
3. Variable-length(가변 인자) asterisk
만약 함수의 parameter가 정해지지 않았다면?
가 정해지지 않은 변수를 함수의 parameter로 사용하는 법
Keyword argument와 함께, argument 사용 가능
Asterisk(*) 기호를 사용하여 함수의 parameter를 표시함
입력된 값은 tuple type으로 사용할 수 있음
가변 인자는 오직 한 개만 맨 마지막 parameter 위치에 사용가능
def asterisk_test(a, b, ):
return a+b+sum() # tuple type으로 입력됨
print(asterisk_test(1, 2, 3, 4, 5))
4. Keyword variable-length
parameter 이름을 따로 지정하지 않고 입력하는 방법
asterisk(**) 두 개를 사용하여 함수의 parameter를 표시함
입력된 값은 type으로 사용할 수 있음
가변인자는 오직 한 개만 기존 가변인자 다음에 사용
def kwargs_test_1():
print() # dict type으로 값을 입력
kwargs_test_1(first = 1, second = 2, third = 3)
# {'first' : 1, 'second' : 2, 'third' : 3}
def kwargs_test_2(one, two, , ):
print(one + two + sum())
print()
kwargs_test_2(3, 4, 5, 6, 7, 8, 9, first = 3, secon = 2, third = 5)
asterisk
- 단순 곱셈
- 제곱 연산
- 가변 인자
- tuple, dict 등 자료형에 들어가 있는 값을 ( a container)
- 함수의 입력값, zip 등에 유용하게 사용가능
def asterisk_test(a, *args):
print(a, *args)
print(a, args)
print(type(args))
test = (2, 3, 4, 5, 6)
asterisk_test(1, *test)
# 1
# 1
# <class 'tuple'>
asterisk_test(1, test)
# 1
# 1 # *args는 튜플로 받기 때문에 형태의 튜플이 된다
# <class 'tuple'>
댓글남기기