일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 코드스테이츠
- OS
- typeScript
- 자료구조
- Computer Science
- node.js
- 운영체제
- 자바스크립트
- 비동기
- Zerobase
- Python
- 컴퓨터공학
- REACT
- python algorithm
- algorithm
- Operating System
- 프로그래머스
- 자바
- execution context
- 파이썬
- useState
- JavaScript
- 알고리즘
- 개발공부
- codestates
- 글또
- java
- react 기초
- context switching
- 파이썬 알고리즘 인터뷰
- Today
- Total
Back to the Basics
[ Python Algorithm Interview] - 파이썬 문법 1 본문
몇 개월 전에 배웠던 파이썬 알고리즘 인터뷰라는 책은 구입하여 공부하고 있었다.
5개월 전까지는 나름 열심히 했는데, 정처기 공부를 하게 되고 지금 코드스테이츠를 하게 되면서 이 책은 책장 안에 데코레이션처럼 들어가 있었다.
조금 아깝기도 하고, 알고리즘 공부와 함께 파이썬도 다시 공부해 볼 겸 꺼내 들었다. 물론 일주일에 1-2번 보겠지만 꾸준히 하다 보면 결국 반 이상은 하지 않을까 싶은 마음이다..
이번 포스팅은 이 책의 초반에 소개되는 이후의 알고리즘 리뷰를 위한 파이썬 주요 문법에 대해 간략하게 정리해보겠다. (이미 깃에 정리한 것을 여기다 조금 보기 좋게 정리하는 것이지만)
<파이썬 알고리즘 인터뷰-2부 3장 Python>
Python 문법
인데트(Indent) :
- PEP 8에 따라 공백 4칸을 원칙으로 함
- PEP(Python Enhncement Proposals, 파이썬 개선 제안서)
- PEP 8 : 파이썬 코딩 스타일 가이드
네이밍 컨벤션 (Naming Convention) :
- Python은 PEP 8을 통해 Snake Case 방식의 네이밍 컨벤션을 권장한다.
타입 힌트(Type Hint) :
- PEP 484 문서에 추가됨.
- s:str="1"
b:int=1 - def fn(a:int)->bool
- Type Hint를 사용하게 되면 fn() 함수의 파라미터 a가 정수형 임을 분명하게 알 수 있음.
- 리턴 값이 bool이라는 것도 알 수 있음.
- $ pip install mypy를 설치하여 사용하면 타입 힌트에 오류가 없는지 자동으로 확인할 수 있다. (타입 힌트가 잘못 지정된 코드는 Incompatible return value type 오류가 발생함)
리스트 컴프리헨션(List Comprehension)
기존의 리스트를 기반으로 새로운 리스트를 만들어내는 구문
람다 표현식에 map이나 filter를 섞어서 사용하는 것에 비해 가독성이 높다.
대체로 표현식은 2개를 넘지 않아야 한다.
EX) 홀수인 경우 2를 곱해 출력
List comprehension 사용하지 않을 경우
a=[] for n in range(1,10+1): if n%2==1: a.append(n*2) >>>a [2,6,10,14,28]
List comprehension 사용할 경우
[n*2 for n in range(1,1+10) if n%2==1] [2,6,10,14,18]
2.7 버전 이후 Dictionary 등이 가능하도록 추가됨
a={} for key, value in original.items(): a[key]=value # Dictionary comprehension 사용 a={key:value for key,value in original.items()}
제너레이터(Generator)
루프의 반복(Iteration) 동작을 제어할 수 있는 루틴 형태
yield 구문을 사용하여 제너레이터를 리턴한다.
yield는 중간값을 리턴한 다음 함수는 종료되지 않고 계속해서 맨 끝에 도달할 때까지 실행된다.
while True 구문은 종료 조건이 없으므로 계속해서 값을 내보낼 수 있다.
>>> def get_natural_number(): n=0 while True: n+=1 yield n # 함수의 리턴값은 다음과 같이 제너레이터가 된다. >>> get_natural_number() <generator object get_natural_number at 0x10d3139d0>
다음 값을 생셩하려면 next()로 추출한다.
>>> g=get_natural_numbers() >>> for _ in range(0,100): print(next(g))
제너레이터는 여러 타입의 값을 하나의 함수에서 생성하는 것도 가능.
>>> def generator(): yield 1 yield 'strign' yield True >>> g=generator() >>> g <generator object generator at 0x10~~> >>> next(g) 1 >>> next(g) 'string' >>> next(g) True
range
- 제너레이터의 방식을 활용하는 대표적인 함수
- range()는 range 클래스를 리턴한다
- for 문에서 사용할 경우 내부적으로 제너레이터의 next()를 호출하둣 매번 다음 숫자를 생성한다.
- 숫자 100만 개를 생성하는 2가지 방법
>>> a=[n for n in range(1000000)] >>> b=range(1000000) >>> len(a) 1000000 >>> len(b) 1000000 >>> len(a)==len(b) True # a는 이미 생성된 겂이 담겨있고, b는 생성해야 한다는 조건만 존재 >>> b range(0,1000000) >>> type(b) <class 'range'>
# 메모리 점유율 비교 >>> sys.getsizeof(a) 8697464 >>> sys.getsizeof(b) # 생성 조건만 보관하므로 메모리 점유율이 적다 48 # 인덱스로 접근 시 바로 생성한다. >>> b[999] 999
enumerate
순서가 있는 자료현(list, set, tuple)등을 인덱스를 포함한 enumerate 객체로 리턴함.
>>> a=[1,2,3,2,45,2,5] >>> a [1,2,3,2,45,2,5] >>> enumerate(a) <enumerate object at 0x0110f830> >>> list(enumerate(a)) [(0,1),(1,2),(2,3),(3,2),(4,45),(5,2),(6,5)]
list()로 결과 추출 가능
list의 인덱스와 값을 함께 출력
for i,v in enumerate(a): print(i,v)
print
# 콤마로 구분 : 한 칸 공백이 디폴트 구분자로 설정되어있다.
>>> print('A1','A2') A1 A2
# sep 파라미터로 구분자 수정 가능
>>> print('A1','A2',sep=',') A1,A2
# end 파라미터를 공백으로 처리하여 줄바꿈 하지 않도록 제한
>>> print('aa',end=' ')
>>> print('bb') aa bb
# 리스트를 출력할 때는 join()으로 묶어서 처리
>>> a=['A','B']
>>> print(' '.join(a)) A B
# .format 사용
idx=1 fruit='Apple'
# 1. idx값에 1을 더해서 fruit와 함께 출력
>>> print('{0}: {1}'.format(idx+1,fruit)) 2: Apple
# 2. 인덱스 생략
>>> print('{}: {}'.format(idx+1,fruit)) 2: Apple
# f-string(formated string literal) 방법
# python 3.6+ 에서만 지원 (이하 버전 동작X)
>>> print(f'{idx+1}:{fruit}') 2: Apple
pass
Null operation으로 아무것도 하지 않는 기능
class MyClass(object): def method_a(self): # 여기에 pass 추가 pass def method_b(self): print("Method B") c=MyClass()
pass는 먼저 Mockup 인터페이스부터 구현한 다음에 추후 구현을 진행할 수 있게 한다.
locals
locals()는 로컬 심벌 테이블 딕셔너리를 가져오는 메서드로 업데이트 또한 가능하다
로컬에 선언된 모든 변수를 조회 가능
디버깅에 많은 도움이 된다
클래스의 특정 메소드 내부에서나 함수 내부의 로컬 정보를 조회해 잘못 선언한 부분이 없는지 확인하는 용도로 활용 가능
출력 방법
import pprint pprint.pprint(locals()) # pprint로 출력하게 되면 가독성이 높다 {'nums': [2,7,11,15], 'pprint': <module 'pprint' from '/user/lib/python3.8/pprint.py'>, 'target': 9}
클래스 메소드 내부의 모든 로컬 변수를 출력해 주기 때문에 디버깅에 많은 도움이 된다.
구글 파이썬 스타일 가이드
함수의 기본값으로 가변 객체(Mutable Object)를 사용하지 않아야 한다. (함수가 객체를 수정하면 기본값이 변경되기 때문)
def foo(a,b=[]): def foo(a,b:Mapping={}):
불변 객체(Immutable Object)를 사용한다.
None을 명시적으로 할당하는 것도 좋은 방법
def foo(a,b=None): if b is None: b=[] def foo(a,b:Optional[Sequence]=None): if b is None: b=[]
True , False를 판별할 때는 암시적(Implicit)인 방법을 사용하는 편이 간결하고 가독성이 높다.
# len(users)==0 길이가 없다는 말은 값이 없다는 뜻이므로 not users로도 충분하다 # YES if not users: print('no users') # No if len(users)==0: print('no users')
# 정수를 처리할 때는 암시적으로 거짓 여부를 판별하기 보다는, 비교 대상이 되는 정수값을 직접 비교하는 편이 덜 위험하다.
# YES
if foo==0:
self.handle_zero()
# No
if foo is not None and not foo:
self.hanele_zeros()
# i%10==0로 명시적으로 값을 비교하는 것이 좋다.
# YES
if 1%10==0:
self.handle_multiple_of_ten()
# No
if not i %10:
self.handle_multiple_of_ten()
- 세미콜론으로 줄을 끝내서는 안된다.
- 최대 줄 길이는 80자로 한다
파이썬 철학
파이썬다운 방식
import thsi
The Zen of Python, by Tim peters
" 문제를 풀어낼 -바람직하고도 유일하며 -명확한 방법이 존재할 것이다."
'Programming Languages > Python' 카테고리의 다른 글
[Python Datastructure ] 배열 - appen operation 시간복잡도 with 분할상환분석 (0) | 2021.10.12 |
---|---|
[Python Algorithm Interview ] 2.6 - 문자열 조작 (0) | 2021.09.08 |
[Python Algorithm Interview ] 2.5 - List & Dictionary (0) | 2021.09.08 |
[ Python Algorithm Interview] - 파이썬 문법 2 (1) | 2021.09.01 |
[Python]Mac에 파이썬 개발환경 설정하기 (0) | 2021.06.02 |