Back to the Basics

[ Python Algorithm Interview] - 파이썬 문법 1 본문

Programming Languages/Python

[ Python Algorithm Interview] - 파이썬 문법 1

9Jaeng 2021. 9. 1. 00:21
728x90

몇 개월 전에 배웠던 파이썬 알고리즘 인터뷰라는 책은 구입하여 공부하고 있었다.
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

" 문제를 풀어낼 -바람직하고도 유일하며 -명확한 방법이 존재할 것이다."

728x90
Comments