코드리뷰를 통해 배우는 파이썬
- inline if else의 사용
파이썬에서는
condition ? a : b
와같은 삼항 연산자 대신에a if condition else b
와 같은 형태로 쓸 수 있다. - list의
pop(0)
연산은 O(n) 파이썬 List는 다양한 연산을 지원하지만 기본적으로 가변 배열 기반이므로pop(0)
연산이 O(n)의 시간복잡도를 가진다. 따라서 큐의 형태로 쓰인다면deque
모듈을 사용하여popleft()
연산을 사용하는 편이 O(1)의 시간복잡도를 가져 더 좋은 성능을 낼 수 있다. - 무한 혹은 경계 값이 필요할 경우
sys
모듈의maxsize
를 사용하거나, 코딩테스트에서sys
모듈을 사용할 수 없다면,float('inf')
를 활용할 수 있다. - PEP8 규칙을 지키자 https://www.python.org/dev/peps/pep-0008
-
파이썬의 문자열 슬라이싱은 범위를 벗어나면 빈 문자열을 반환한다.
>>> s = 'hello world! this is python3' >>> print(s[len(s):999]) >>> type(s[len(s):999]) <class 'str'> >>> len(s[len(s):999]) 0
- 마지막 인덱스에 접근할 때에는
len() - 1
보다는-1
로 접근한다. zip()
을 활용해서 iterable한 것을 묶어서 사용할 수 있다.- 전역변수를 사용하기 보단 nested function(중첩 함수)를 사용하자(코드가 지저분해지지 않는 선에서)
- 파이썬에서 재귀 호출은 매우 느리고 꼬리재귀도 지원이 되지 않기 때문에 stack을 활용해서 재귀 구조를 풀어놓는게 좋다.
-
extend()
의 활용extend()
는 내부의 iterable을 값만 추가해주는 함수다.dx = [0, 1, 0, -1] dy = [1, 0, -1, 0] ... q.extend([(a + x, b + y) for x, y in zip(dx, dy)])
위와 같은 형태로 활용할 수 있다. https://m.blog.naver.com/PostView.nhn?blogId=wideeyed&logNo=221541104629&categoryNo=50
- 파이썬은
try ~ except
를 통해 예외처리를 한다. Java처럼 사전에 예외조건을 캐치하고 미리 방지하는 방어적인 방식이 아니다. https://suwoni-codelab.com/python%20%EA%B8%B0%EB%B3%B8/2018/03/06/Python-Basic-EAFP/ heappop()
후heappush()
를 한다면heapreplace()
사용을 고려해보자. 로직도 간단해지고 보기 좋아진다.- 좀 더 파이써닉하게 코드 짜는 법
for ~ else
문법,list comprehension
같은 파이썬에서만 존재하는 문법을 가능하면 적극적으로 사용하도록 노력한다. -
python
for ~ else
문법 https://itholic.github.io/python-for-else/else
아래는 for 문이 끊김 없이 다 돌았을 때 동작함for ~ else문은 “for문에서 break가 발생하지 않았을 경우”의 동작을 else문에 적어주는 것이다.
-
N x M 크기의 2차원 리스트 초기화 방법
n = 3 m = 3 array = [[0] * m for _ in range(n)]
-
문자열 padding 하는 법(0말고 다른 문자도 가능한 방법도 존재)
str.zfill(size)
함수 사용(0으로 크기 벗어난 값 채움)str.rjust(size, fill_char)
함수 사용(fill_char
로 채움)fill_char
의 길이는 1글자로 제한됨
-
format()
의 활용- 이진수 변환:
format(number, 'b')
- zero padding 이진수 변환:
format(number, '0' + str(size) + 'b')
0b
prefix 이진수 변환:format(number, '#0' + str(size) + 'b')
주의: 0b도 자릿수에 포함됨.
- 이진수 변환:
- 진법 변환시 주의할 점
진법 변환 후 prefix가 붙어서 보통
bin(number)[2:]
와 같은 형태로 prefix를 제거함 -
숫자 비트연산 방법
- AND연산:
num1 & num2
- OR 연산:
num1 | num2
- XOR연산:
num1 ^ num2
- NOT연산:
~num1
- AND연산:
- 문자열 치환
str.replace(search_str, replace_str[, count])
search_str
: 탐색할 문자열replace_str
: 대체할 문자열count
: 치환할 횟수 주의: 정규표현식은 지원하지 않음. 정규표현식을 사용하려면re
모듈의sub
함수를 사용한다. -
n * m 이차원 배열 90도 회전
def rotate_a_matrix_by_90_degree(a): return [list(reversed(i) for i in zip(*key))]
- 파이썬의 리스트는 편의 연산자 때문에 생각과는 다르게 동작할 수 있다.
+
연산자를 쓰면 뒤에 append가 된다.*
연산자를 쓰면 리스트의 요소를 여러개 복사할 수 있다. (이건 초기화할 때 많이 사용) - 파이썬은 문자열과 정수형의 합연산시에 타입 변환을 자동으로 해주지 않는다!! (Java와 차이점)
-
파이썬의 list comprehension 잘 사용하기
for x in list: if x == y: count += 1
이런 코드는
count += [1 for x in list if x == y]
로 변경하는게 더 파이써닉하다.
-
파이썬의
*
(asterisk, 언팩 연산자)란? 파이썬의*
는 튜플이나, 리스트의 요소를 풀어 헤칠 수 있다.a = ('a', 'b', 'c', 'd') b = [1, 2, 3, 4] >>> print(*a) a b c d >>> print(*b) 1 2 3 4
응용해서 zip 함수와 함께 사용하는 예
a = [('A', 13), ('B', 14), ('C', 15)] >>> list(zip(*a)) # 내부 요소가 튜플로 나온다 [('A', 'B', 'C'), (13, 14, 15)] >>> list(map(list, zip(*a))) # 튜플에 list 함수를 적용한다. [['A', 'B', 'C'], [13, 14, 15]]
- 파이썬의 collections 모듈의 defaultdict 사용시 주의할 점
python의 defaultdict는 키가 없는 값 조회시 default값을 생성한다.
여기서 발생하는 문제가 바로
for ... in
구문을 사용할 떄 발생한다. 존재하지 않는 키로 검색할 때, default값을 생성하면서 크기가 변하게 되기 때문이다. 이런 문제상황을 해결할 때에는list()
로 감싸주어 복사본을 생성해주면 된다. -
nonlocal
사용법 파이썬에서는 중첩함수를 지원하는데, 중첩함수 내부에서 외부 함수의 변수를 사용하고 싶을 때가 있을 수 있다. 이 때, 해당 변수에nonlocal variable
과 같은 식으로 선언해주면 binding 가능한 해당 변수를 찾는다. 단, 전역 변수는 해당되지 않는다.x = 0 def func(): nonlocal x x = 33 func() print(x)
위와 같이는 사용할 수 없다.
no binding for nonlocal 'x' found
가 발생한다. 애초에 전역변수를 사용하려고 하지 않는 것이 좋다.def func1(): x = 0 def func2(): nonlocal x x = 33 func2() print(x) # 33출력
-
list의
count(element)
는 요소를 넣어주면 요소의 개수를 반환한다.>>> a = [1, 1, 1, 3, 2, 2, 1] >>> a.count(1) 4