책읽기

[파이썬 알고리즘 인터뷰] 2부 - 파이썬 (~ 3장 - 파이썬)

pythaac 2021. 6. 29. 11:36

 

이 글은 "파이썬 알고리즘 인터뷰 (박상길 지음)"을 읽고 주관적으로 요약한 글입니다. 

출처 : http://www.yes24.com/Product/Goods/91084402

3장 파이썬

  • 파이썬은?
    • 네덜란드 컴퓨터 과학자 귀도 반 로섬 (Guido Van Rossum)이 만듦
    • 파이썬의 원칙
      1. 읽기 쉬워야함
        - 중괄호 -> 인덴트
      2. 사용자가 모듈패키지 생성/배포가 가능해야함
        - pip를 통해 패키지 인덱스 제공
    • 인공지능을 주도하는 표준 언어
    • 연구개발의 주력 언어

1) 파이썬에 대한 이해

  • 파이썬에 대한 깊은 이해가 필요함
    • 언어의 세부 구현을 상세히 알아야 문제를 제대로, 신속하게, 정확하게 풀 수 있음
    • 제대로 사용법을 숙지해야 제대로 사용할 수 있음
    • 파이썬 공식 인터프리터 Cpython (Pypy도 있음)

2) 파이썬 문법

요약

  1. 인덴트 : 4칸 공백
  2. 네이밍 컨벤션 : 스네이크 케이스
  3. 타입 힌트 : 함수 input/output 타입 명시
  4. 리스트 컴프리헨션 : [ n for range(0, 100 + 1) if n % 2 == 0 ]
  5. 제너레이터 : yield를 이용해 루프문 제어
  6. range : 제네레이터로, 메모리 효율이 좋으며, 인덱스로 바로 접근 가능
  7. enumerate : 각 인덱스와 pair로 반환 -> enumerate(['a', 'b', 'c']) = [ (0, 'a'), (1, 'b'), (2,'c') ]
  8. // 나눗셈 연산자 : 몫만 구할때 사용, 몫+나머지 = divmod()
  9. print : 1) ,는 공백 1칸  2) sep으로 , 구분자 변경  3) end로 \n 변경,  4) f-string : print( f'{idx + 1}: {fruit}')
  10. pass : 빈 함수를 만들 때 인덴트 오류 방지
  11. locals : 로컬에 선언된 변수 조회, pprint(locals())
  • 인덴트
    • PEP(Python Enhancement Proposal) 8에 의해 "공백 4칸"이 원칙
    • tab 사용이 불가능하진 않겠지만, 공백 4칸을 권장함

  • 네이밍 컨밴션
    • 스네이크 케이스 사용
  • 타입 힌트
    • 가독성을 떨어뜨리고, 버그를 유발시키므로 사용 권장
    • mypy를 사용해 타입 힌트 오류 확인 가능
def fn(a: int) -> bool:
  • 리스트 컴프리헨션
    • 파이썬에서는 map, filter와 같은 "함수형" 기능을 지원
    • 람다 표현식도 지원
    • 그러나 리스트 컴프리헨션이 더욱 유용한 기능
      List Comprehension : 기존 리스트를 기반으로 새로운 리스트를 만들어내는 구문
    • 딕셔너리 컴프리헨션도 제공
# 파이썬의 map, lambda 사용

list(map(lambda x: x + 10, [1,2,3]))
# [11, 12, 13]
# 홀수인 경우 2를 곱한 값의 리스트

# 1. 리스트 컴프리헨션
[n * 2 for n in range(1, 10 + 1) if n % 2 == 1]

# 2. 일반 구현
a = []
for n in range(1, 10 + 1):
    if n % 2 == 1:
        a.append(n * 2)

# [2, 6, 10, 14, 18]
# 1. 딕셔너리 컴프리헨션
a = {key: value for key, value in original.items()}

# 2. 일반 구현
a = {}
for key, value in original.items():
    a[key] = value
  • 제너레이터
    • Generator : 루프의 반복 동작을 제어할 수 있는 루틴 형태
    • 반복문을 yield를 만날 때까지 진행, return 후 멈춤
    • next를 통해 반복 동작 진행 가능
def generator():
    yield 1
    yield 'string'
    yield True
    
g = generator()

next(g) 
# 1
next(g)
# 'string'
next(g)
# True
  • range
    • 제너레이터를 활용하는 대표적인 함수
    • 파이썬 2.x에서는 숫자를 미리 생성해서 리스트로 리턴하는 방식이었음
    • 버전 3 이후 제너레이터 range 클래스를 리턴하는 형태로 변경
    • 메모리 점유율에서 매우 좋음
    • 인덱스로 접근 시에 바로 생성하도록 구현
# 메모리 점유율 비교

a = [n for n in range(1000000)]
b = range(1000000)

len(a)
# 1000000
len(b)
# 1000000
a == b
# True

sys.getsizeof(a)
# 8697464
sys.getsizeof(b)
# 48
# 인덱스로 접근

b = range(1000000)

b[999]
# 999
  • enumerate
    • 여러 가지 자료형(list, set, tuple 등)을 인덱스를 포함한 enumerate 객체로 리턴
a = [1, 2, 3, 2, 45, 2, 5]

list(enumerate(a))
# (인덱스, 값)
# [(0, 1), (1, 2), (2, 3), (3, 2), (4, 45), (5, 2), (6, 5)]
  • // 나눗셈 연산자
    • 몫만 구할 때 : //
    • 나머지만 구할 때 : %
    • 몫, 나머지 모두 구할 때 : divmod
##### 1. '/' 연산자 #####
5 / 3
# 1.6666666666666667

##### 2. '//' 연산자 #####
5 // 3
# 1

##### 3. '%' 연산자 #####
5 % 3
# 2

##### 4. divmod #####
divmod(5, 3)
# (1, 2)
  • print
    • 코딩 테스트 시에는 디버거 사용 or TDD 방식 접근이 어려움
    • 사실상 print()가 디버깅을 위해 제공되는 유일한 기능 (개인적으로 테스트는 print로 디버깅이 어렵단 생각이지만 시도해보기)
    • 파라미터 설정
      1. 콤마( , )
        한 칸 공백(구분자)으로 출력
      2. sep
        콤마로 구분된 string들의 구분자 수정
      3. end
        줄바꿈 대신 마지막 char 설정
    • 출력 포멧
      1. format을 이용
      2. f-string : format 방식에 비해 훨씬 간결하고, 직관적이고, 속도도 빠름
idx = 1
fruit = "Apple"

print('{0}: {1}'.format(idx + 1, fruit))
print('{}: {}'.format(idx + 1, fruit))
print(f'{idx + 1}: {fruit}')
# 2: Apple
  • pass
    • pass는 널(NULL) 연산으로 아무것도 하지 않는 기능
    • 목업(mockup) 인터페이스를 먼저 구현할 때 인덴트 오류 방지 가능
class MyClass(object):
    def method_a(self):
        # 인덴트 오류 방지
        pass
    
    def method_b(self):
        print("Method B")

c = MyClass()
  • locals
    • 로컬 심볼 테이블 딕셔너리를 가져오는 메소드
    • 로컬에 선언된 모든 변수를 조회할 수 있음
    • pprint로 출력시 보기편함
import pprint
pprint.pprint(locals())

# {'nums': [2, 7, 11, 15],
# ...
# 'target' : 9}

3) 코딩 스타일

※ 요약 : 코테의 경우 코드의 품질이 평가될 수 있으므로, 간단한 주석, 명료한 리스트 컨프리헨션, 구글 파이썬 스타일 가이드 참고 등으로 가독성이 높은 코드를 작성할 것

  • 코딩 테스트에서의 코딩 스타일
    • 코딩 스타일은 코딩 테스트의 점수에는 영향이 없을 수 있음
    • 그러나 채용을 위한 코딩 테스트는 제출한 코드의 품질을 평가할 수 있음
    • "왜 코드를 이렇게 작성했나요?"에 대한 대답을 할 수 있어야 함
    • 추천 도서
      - Clean Code 클린 코드 (로버트 C. 마틴 지음, 박재호 외 옮김, 인사이트, 2013)
      - 프로그래밍 수련법 (브라이언 W. 커니핸, 롭 파이크 지음, 김정민 옮김, 인사이트, 2008)
  • 실무에서의 파이썬 코딩 스타일
    • PEP 8, 구글의 파이썬 스타일 가이드는 실용적 관점에서 도움됨
    • 코딩 스타일은 가능한 많은 사람이 선호하는 방식으로 선택할 것
    • 모두가 이해할 수 있을 때 더 높은 가치를 발휘하는 것이 좋은 코드
  • 변수명과 주석
    • "클린 코드"에서는 코드(JAVA)에 주석을 달지 말라고 주장 (??? 매우 궁금한 부분)
    • 그러나 주석이 없으면 변수명의 의미, 동작 방식을 파악하기 쉽지 않음
    • 파이썬은 간단한 주석이 더 가독성이 높음
    • 주석은 영어로 작성
  • 리스트 컴프리헨션
    • 지나치게 남발하게되면 파이썬의 가독성을 떨어트리는 요인
    • 한줄로 적게 되는 경우가 많은데, 역할별로 줄을 구분하면 더 가독성이 오름
    • 모두 풀어서 쓰는 것도 가독성을 위해 검토해볼 수 있음
    • 아래는 지나치게 가독성이 떨어진 경우 (개인적으로는 코딩 테스트에서 나쁘지 않은 방식인듯)
return [(x, y, z)
        for x in range(5)
        for y in range(5)
        if x != y
        for z in range(5)
        if y != z]
  • 구글 파이썬 스타일 가이드
 

구글 파이썬 스타일 가이드 - 2.12 Default Argument Values (Mutable vs Immutable)

1. 구글 파이썬 가이드 - Default Argument Values "파이썬 알고리즘 인터뷰"라는 책을 쭉 읽으면서 그냥 넘어가지 못한 구간이 있다. 구글 파이썬 스타일 가이드를 설명하던 중, 아래와 같은 글귀와 코

pythaac.tistory.com