2024. 9. 9. 15:26ㆍ학습/python
A이면 B이다. ~B이면 ~A이다.
If P, Then Q. If not Q, Then not P.
대우를 활용해서 파이썬에서 코드 최적화 방법에 대해 정리해본다.
1. 조건문 최적화
2. 예외 처리
3. 논리적 동치 != 복잡도
- O(1) -> O(n) 되는 경우
1. 조건문 최적화
# 원래 조건문
if not (P and Q):
do_something()
# 대우를 활용한 조건문
if not P or not Q:
do_something()
not (P and Q) == not P or not Q
드 모르간 법칙.
논리적으로는 동치지만 코드 최적화 부분에서는 느낌이지만 미세하게나마 차이가 존재한다.
1.1 차이
- 둘 다 모두 O(1) 이다.
- 다만 전자의 경우 P가 False 일 경우에도 Q를 판단해야 한다.
- 후자의 경우 P가 False 일 경우 즉시 전체 조건이 True 가 되어 Q를 판단하지 않아도 된다.
- 단락 평가(short-circuit evaluation)
1.2 기타
- 가독성 은 취향차이라고 생각.
- 후자를 사용해 쬐에에에끔이나마 최적화에 관심이 있다는것을 어필할 수 있음.
2. 예외 처리
def process_data(data):
# 원래 조건
if data is not None and len(data) > 0:
# 데이터 처리
pass
else:
raise ValueError("유효하지 않은 데이터임")
# 대우를 활용한 조건
if data is None or len(data) == 0:
raise ValueError("유효하지 않은 데이터임")
# 데이터 처리
2.1 차이
- 역시 둘다 모두 O(1).
- 후자가 유효하지 않은 데이터를 더 빨리 감지할 수 있다.
data is None이 True라면 len(data)를 확인하지 않고 바로 예외를 발생. - 빠른 실패(Fail-fast)의 구현
3. 논리적 동치 != 복잡도
# 원래 조건
if not (x < 0 or x > 100):
print("0 과 100 사이에 있어!")
# 대우를 활용한 조건
if 0 <= x <= 100:
print("0과 100 사이에 있어!")
억지춘향 느낌이 나는 예시.
1,2 번 예시와 비슷한 장점이 있음.
다만 공부하면서 논리적으로 동치지만 주의해야하는 점들이 몇몇 있었는데,
아래에 설명.
# 원래 조건
if not (s == "" or s == " "):
print("s는 빈 문자열이 아님")
# 대우를 활용한 조건
if s.strip(): # strip() 메서드를 이용해 공백을 제거
print("s는 빈 문자열이 아님")
if not (s == "" or s == " ")
문자열 s가 빈 문자열이거나 공백 문자열일 때 False를 반환.
즉, s가 비어 있지 않거나 공백이 아닐 때 True를 반환함.
if s.strip():
s의 양쪽 공백을 제거한 후, 그 결과가 비어 있지 않으면 True를 반환.
즉, s가 빈 문자열이거나 공백만 있을 경우 False를 반환.
두 조건문은 모두 문자열 s에 공백 이외의 문자가 존재하는 경우에 참이 되므로, 논리적으로 동치입니다..
즉, 두 조건문 중 어느 것을 사용해도 동일한 결과를 얻을 수 있다.
다만 복잡도에서 큰 차이가 있는데,
3.1 시간 복잡도
if not (s == "" or s == " ")
- 문자열 비교 연산이 2번 수행됨.
- O(1)
if s.strip():
- strip()은 문자열 전체를 한 번 스캔하여 양쪽 끝의 공백을 제거함.
- O(n)
3.2 공간 복잡도
if not (s == "" or s == " ")
- O(1)
if s.strip():
- 원본 문자열을 수정하지 않고 새로운 문자열을 생성.
- 최악의 경우, 원본 문자열과 동일한 크기의 새로운 문자열이 생성될 수 있음.
- O(n)
시간과 공간 복잡도 모두 O(1)이 O(n)으로 증가하는 대참사가 발생한다...
항상 메서드나 함수를 사용할 때 주의해야하는 점이다...
'학습 > python' 카테고리의 다른 글
[threading] ipynb에서 daemon thread 가 적용되지 않는 것에 대해서 (0) | 2024.03.05 |
---|---|
나머지 // , int.__floordiv__ (0) | 2023.09.13 |
lambda(람다) -2, def 함수 문법과 lambda 문법의 차이 (0) | 2023.05.22 |
lambda(람다) -1, lambda의 정의, 제작의도 (0) | 2023.05.22 |
map() -1 map동작 원리, 그냥 list 안에 for 문 쓰면 안됨?? (0) | 2023.05.22 |