8. 파이썬 잘하는 척 해보자

8. 파이썬 잘하는 척 해보자

8-2. 파이썬 어디까지 써 봤니?!

  1. 퍼포먼스(성능)
    • 어떤 언어든 코드를 짜서 실행을 시켰을 때 얼마나 처리 속도
    • 특정한 연산을 빠르게 수행
    • C 언어가 퍼포먼스 상위, 파이썬은 상대적으로 하위
  2. 생산성
    • 똑같은 기능을 하는 프로그램을 얼마나 빨리 작성 가능도
    • C 언어가 생산성 하위, 파이썬은 상대적으로 상위
  3. 퍼포먼스 vs 생산성
    • trade-off : 두 개의 위치가 상하의 위치름 가지는 것
  4. 파이썬의 성능
    • 높은 생산성
      • pip를 이용한 간단한 설치
      • 많은 라이브러리 존재
    • 코드의 간결함
    • 빠른 개발 속도
    • 스크립트 언어(인터프리터 언어)
  5. 컴파일 언어, 인터프리터 언어 비교
    • 컴파일 언어
      • 실행 전 소스 코드를 컴파일하여 기계어로 변환 후 해당 파일을 실행
      • 이미 기계어로 변환된 것을 실행하므로 비교적 빠름
      • 컴파일 시점에 소스 코드의 오류를 잡기 쉬움
      • 같은 소스 코드도 다른 환경(PC, mobile 등)에서 실행시 다시 컴파일 필요
    • 스크립트 언어(인터프리터 언어)
      • 코드를 작성함과 동시에 인터프리터가 기계어로 번역하고 실행
      • 코드 번역 과정이 있어 비교적 느림
      • 주 사용 목적이 뚜렷하게 개발되어 사용하기 쉬운 편
      • 명령줄로 코드를 즉시 실행할 수 있음
    • <참고> https://ko.wikipedia.org/wiki/Interpreter_(computing)

8-3. 파이썬을 더 잘 사용해보자! (1) for문 잘 사용하기

  • enumerate(), 이중for문, list Comprehension, Generator
  1. for문
    • 반복적으로 코드를 쓰지 않아도 돼 간결한 코드를 만드는 데 큰 도움
    • <예제코드> my_list에 있는 값들을 하나씩 출력
      <예제코드> my_list에 있는 값들을 하나씩 출력
      my_list = ['a','b','c','d']
      
      for i in my_list:
          print("값 : ", i)
  1. enumerate()

    • 리스트의 인덱스 번호와 값을 함께 반환
    • <예제코드> my_list에 있는 인덱스 번호와 값을 함께 출력
    <예제코드> my_list에 있는 인덱스 번호와 값을 함께 출력
    my_list = ['a','b','c','d']
    
    for i, value in enumerate(my_list):
    		print("순번 : ", i, " , 값 : ", value)
  1. 이중 for문

    • <예제코드> 2개의 시퀀스 객체의 값으로 새로운 객체 만들기
    <예제코드> 2개의 시퀀스 객체의 값으로 새로운 객체 만들기
    my_list = ['a','b','c','d']
    result_list = []
    
    for i in range(2):
        for j in my_list:
            result_list.append((i, j))
            
    print(result_list)
  1. 컴프리헨션(Comprehension)

    • 순회형 컨테이너 객체로부터 이를 가공한 새로운 순회형 객체를 생성
    • 리스트(List), 셋(Set), 딕셔너리(Dict) 가능
    • <예제코드> 리스트, range를 조합해 새로운 요소의 리스트 만들기
    <예제코드> 리스트, range를 조합해 새로운 요소의 리스트 만들기
    my_list = ['a','b','c','d']
    
    result_list = [(i, j) for i in range(2) for j in my_list]
    
    print(result_list)
  1. 제너레이터(Generator)

    • iterator를 생성해주는 함수, 함수안에 yield 키워드를 사용
      • yield : 실행의 순서를 밖으로 "양보"
    • genrator 특징
      • iterable한 순서가 지정됨(모든 generator는 iterator)
      • 무한한 순서가 있는 객체를 모델링 가능.(명확한 끝이 없는 데이터 스트림)
    • <예제코드> 메모리 간단화 시키는 제네레이터??
    my_list = ['a','b','c','d']
    
    # 인자로 받은 리스트로부터 데이터를 하나씩 가져오는 제너레이터를 리턴하는 함수
    def get_dataset_generator(my_list):
        result_list = []
        for i in range(2):
            for j in my_list:
                yield (i, j)   # 이 줄이 이전의 append 코드를 대체했습니다
                print('>>  1 data loaded..')
    
    dataset_generator = get_dataset_generator(my_list)
    for X, y in dataset_generator:
        print(X, y)
  1. 한 줄 for문
    • 1개 for문
      • [출력형식 for 변수 in 리스트] 또는 list(식 for 변수 in 리스트)
    • 2개 for문
      • [출력형식 for 변수1 in 리스트1 for 변수2 in 리스트2]
      • list(출력형식 for 변수1 in 리스트1 for 변수2 in 리스트2)

8-4. 파이썬을 더 잘 사용해보자! (2) Try - Except 예외 처리하기

  1. 예외 처리를 위한 방법
    • Try - Except
      • Try : 실행코드

      • Except : 정상동작하지 않았을 때 보완코드 작성

      • 프로그램이 에러 없이 끝나게 하기 위한 방법

        a = 10
        b = 0 
        
        try:
            #실행 코드
            print(a/b)
        		
        except:
            print('에러가 발생했습니다.')
            #에러가 발생했을 때 처리하는 코드
            b = b+1
            print("값 수정 : ", a/b)

8-5. 파이썬을 더 잘 사용해보자! (3) Multiprocessing

  1. Python은 인터프리터 언어

    • 순차진행
    • 단점: 많은 시간 소요
  2. Multiprocessing

    • 병렬연결 : 여러 개를 동시에 진행
    • 시간을 줄여 생산성 향상
  3. Multiprocessing패키지 Pool 클래스

    <예제코드>

    import multiprocessing
    import time
    
    num_list = ['p1','p2', 'p3', 'p4']
    start = time.time()
    
    def count(name):
        for i in range(0, 100000000):
            a = 1+2
        print("finish:"+name+"\n")
        
    
    if __name__ == '__main__':
        pool = multiprocessing.Pool(processes = 4)
        pool.map(count, num_list)
        pool.close()
        pool.join()
    
    print("time :", time.time() - start)
    • pool = multiprocessing.Pool(processes = 4)
      • Multiprocessing패키지 Pool 클래스를 이용해 pool네이밍
      • 병렬 처리 시, 4개의 프로세스를 사용하도록 지정
      • CPU 코어의 개수만큼 입력해 주면 최대의 효과 가능
    • pool.map(count, num_list)
      • 병렬화를 시키는 함수
      • count 함수에 num_list의 원소들을 하나씩 넣기
      • count('p1'), count('p2'), count('p3'), count('p4') 생성
    • pool.close()
      • 병렬화 부분이 끝날 때 사용
      • 더 이상 pool을 통해서 새로운 작업을 추가하지 않을 때 사용
    • pool.join()
      • 프로세스가 종료될 때까지 대기하도록 지시하는 구문
      • 병렬처리 작업이 끝날 때까지 대기

8-6. 같은 코드 두 번 짜지 말자! (1) 함수 사용하기

  1. 함수란?

list_data = [10, 20, 30, 40]
list_data2 = [20, 30, 40, 50]

def max_function(x):
    length = len(x)
    max_result = x[0]
    for i in range(length):
        if max_result < x[i]:
            max_result = x[i]
    return max_result

print("최댓값은 ", max_function(list_data))
print("최댓값은 ", max_function(list_data2))
  • 코드의 효율성
  • 코드의 재사용성
  • 코드의 가독성

8-7. 같은 코드 두 번 짜지 말자! (2) 함수 사용 팁

  1. pass

    • 틀만 만들어 놓고 에러가 나지 않게 할 때 사용
    • 조건문, 반복문에도 사용 가능
    def empty_function():
        pass
  2. 함수를 연달아 사용 가능

    def say_something(txt):
        return txt
    
    def send(function, count):
        for i in range(count):  
            print(function)
        
    send(say_something("안녕!"), 2)
  3. 함수 안의 함수 & 2개 이상의 return
    -함수1 안의 함수2
    - 함수1 안에서는 호출 가능
    - 함수1 밖에서는 호출 불가능

    ```python
    list_data = [30, 20, 30, 40]
    
    def minmax_function(x_list):
            
        def inner_min_function(x):
            length = len(x)
            min_result = x[0]
            for i in range(length):
                if min_result > x[i]:
                    min_result = x[i]
            return min_result
        
        def inner_max_function(x):
            length = len(x)
            max_result = x[0]
            for i in range(length):
                if max_result < x[i]:
                    max_result = x[i]
            return max_result
            
        x_min = inner_min_function(x_list)
        x_max = inner_max_function(x_list)
        
        minmax_list = [x_min, x_max]
    
        return minmax_list
    
    print("최솟값, 최댓값은 : ", minmax_function(list_data))
    print("최솟값은 : ", minmax_function(list_data)[0])
    print("최댓값은 : ", minmax_function(list_data)[1])
    ```
  4. 여러 변수로 반환하기

    • 함수1의 각각의 값으로 반환
    • 튜플 형태로 언패킹 가능
    list_data = [30, 20, 30, 40]
    
    def minmax_function(x_list):
            
        def inner_min_function(x):
            length = len(x)
            min_result = x[0]
            for i in range(length):
                if min_result > x[i]:
                    min_result = x[i]
            return min_result
        
        def inner_max_function(x):
            length = len(x)
            max_result = x[0]
            for i in range(length):
                if max_result < x[i]:
                    max_result = x[i]
            return max_result
            
        x_min = inner_min_function(x_list)
        x_max = inner_max_function(x_list)
        
        return x_min, x_max
    
    min_value, max_value = minmax_function(list_data)
    
    print("최솟값은 : ", min_value)
    print("최댓값은 : ", max_value)

8-8. 같은 코드 두 번 짜지 말자! (3) 람다 표현식

  1. 람다
    • 런타임에 생성해서 사용할 수 있는 익명 함수
    • 함수 이름이 없는 함수
    • 함수의 인수 부분을 간단히 하기 위함
  2. 사용방법
    • (lambda x, y : x + y)(10, 20)
      • x, y : 입력값
      • x + y : 리턴값
      • 함수에 사용할 데이터 값
  3. <참고> 람다를 자주 사용 하는 함수
    • map(함수, 반복 가능한 객체)
      • 원소를 함수에 적용시켜서 하나씩 결과 반환
      • 반환 map객체로 해석 불가능
      • list, tuple로 형변환 해야 인지 가능
    • reduce(함수, 시퀀스)
      • 원소들을 누적하여 함수에 적용
      • 반환값 : 원소의 데이터 타입
      • 시퀀스 : 문자열, 리스트, 튜플 등
    • filter(함수, 시퀀스)
      • 함수에 적용시켜서 결과가 참인 값만 추출
      • 반환 filter객체로 해석 불가능
      • list, tuple로 형변환 해야 인지 가능

8-9. 같은 코드 두 번 짜지 말자! (4) 클래스, 모듈, 패키지

  1. 클래스
    • 비슷한 역할을 하는 함수들의 집합
  2. 모듈(Module)
    • 함수, 변수, 클래스를 모아 놓은 파일, 코드의 저장소
    • 개인이 직접 ~.py를 만들어 저장 후 import해서 사용 가능
  3. 패키지

8-10. 프로그래밍 패러다임과 함수형 프로그래밍

  1. 패러다임(Paradigm)

    • 어떤 한 시대의 사람들의 견해나 사고를 근본적으로 규정하고 있는 테두리
    • 인식의 체계 또는 사물에 대한 이론적인 틀이나 체계를 의미하는 개념
    • ex) 천동설, 지동설
  2. 절차 지향 프로그래밍

    • 일이 진행되는 순서대로 프로그래밍하는 방법
    • 장점 : 코드가 순차적으로 작성되어 있어 순서대로 읽기만 하면 이해가 가능
    • 단점
      • 위에서 하나가 잘못되면 아래도 연쇄적으로 문제가 생겨서 유지 보수의 어려움
      • 일반적으로 코드 길이가 길어서 코드를 분석의 어려움
  3. 객체 지향 프로그래밍

    • 개발자가 프로그램을 상호작용하는 객체들의 집합
    • 객체를 먼저 작성하고 함수를 작성
    • 이렇게 작성된 객체는 객체 간의 상호작용 가능
    • 장점 : 코드의 재사용, 코드 분석이 또는 아키텍처를 바꾸기 쉬움
    • 단점
      • 객체 간의 상호작용으로 인한 설계에서 많은 시간이 소요
      • 설계를 잘못하면 전체적으로 바꿔야 하는 어려움
    • 파이썬은 객체지향 프로그래밍(OOP, Object Oriented Programming) 패러다임을 기본적으로 지원
      <참고> 파이썬 - OOP Part 1. 객체 지향 프로그래밍(OOP)은 무엇인가? 왜 사용하는가?
      [파이썬 - OOP Part 1. 객체 지향 프로그래밍(OOP)은 무엇인가? 왜 사용하는가? - schoolofweb.net](http://schoolofweb.net/blog/posts/%ED%8C%8C%EC%9D%B4%EC%8D%AC-oop-part-1-%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8Doop%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94%EA%B0%80/)
  4. 함수형 프로그래밍

    • 데이터 사이언티스트에게 적합한 프로그래밍 패러다임
    • 함수로 문제를 분해
      • 함수들은 입력을 받아서 만들어진 출력값은 함수 외부의 다른 변수나 함수의 영향을 받지 않음
    • 장점 : 효율성, 버그 없는 코드, 병렬 프로그래밍
    • GPU를 이용한 병렬 처리 -> AI의 전성기 도래
  5. 함수형 프로그래밍의 특징

    • 순수성
      • 함수 외부의 함수나 변수에 의해 영향을 받지 않음(설계를 그렇게 하는 듯)
    • 모듈성
      • 문제를 작은 조각으로 분해하도록 강제
      • 한 가지 작업을 수행하는 작은 함수들로 쪼개어 만드는 것이 코딩하기에 쉬움
      • 작은 함수는 가독성도 좋고 오류를 확인하기도 더 쉬움
      • 프로그램은 더욱 모듈화
  6. 디버깅과 테스트 용이성

    • 모듈화가 되어서 디버깅, 테스트 용이
    • 디버깅
      • 컴퓨터 프로그램 개발 중에 발생하는 시스템의 논리적인 오류나 비정상적 연산(버그)을 찾아 그 원인을 밝히고 수정하는 작업 과정
    • <참고> https://docs.python.org/ko/3/howto/functional.html

    Functional Programming HOWTO - Python 3.10.1 documentation

8-11. 파이써닉하게 코드를 짜보자

  1. Whitespace

    • 한 줄의 코드 길이가 79자 이하
      y = a + a + a + a # 79자 이하
    • 함수와 클래스는 다른 코드와 빈 줄 두 개로 구분
    class a():
        pass
    # 빈 줄
    # 빈 줄
    class b():
        pass
    # 빈 줄
    # 빈 줄
    def c():
        pass
    # 빈 줄
    # 빈 줄
    • 클래스에서 함수는 빈 줄 하나로 구분
    class a():
    	
    	def b():
    		pass
    	
    	def c():
    		pass
    • 변수 할당 앞뒤에 스페이스를 하나만 사용
    y = 1
    • 리스트 인덱스, 함수 호출에는 스페이스를 사용하지 않음
    my_list = [1, 2, 3]
    my_list[0] # 리스트 인덱스 호출
    
    my_function(0) # 함수 호출
    • 쉼표(,), 쌍점(:), 쌍반점(;) 앞에서는 스페이스를 사용하지 않음
    my_list = [1, 2, 3]; my_list[0:1]
    if len(my_list) == 3: print my_list
  1. 주석

    • 코드의 내용과 일치하지 않는 주석은 피하기
    • 불필요한 주석은 피하기
  2. 이름 규칙

    • 변수명 앞에 _(밑줄)이 붙으면 함수 등의 내부에서만 사용되는 변수
    _my_list = []
    • 변수명 뒤에 _(밑줄)이 붙으면 라이브러리 혹은 파이썬 기본 키워드와의 충돌을 피하고 싶을 때 사용
    import_ = "not_import"
    • 소문자 L, 대문자 O, 대문자 I를 가능하면 사용 금지, 가독성이 굉장히 안 좋음
    • 모듈(Module) 명은 짧은 소문자로 구성되며, 필요하다면 밑줄로 나누기
    my_module.py
    • 클래스 명은 파스칼 케이스(PascalCase) 컨벤션으로 작성
    class MyClass():
    	pass
    • 함수명은 소문자로 구성하되 필요하면 밑줄로 나누기
    def my_function():
    	pass
    • 상수(Constant)는 모듈 단위에서만 정의하고 모든 단어는 대문자, 필요하다면 밑줄로 나누기
    MY_PI = 3.14 # 상수는 변하지 않는 변수입니다.
    1. 네이밍 컨벤션(Naming convention)
      • snake_case
        • 모든 공백을 "_"로 바꾸고 모든 단어는 소문자
        • 파이썬에서는 함수, 변수 등을 명명할 때 사용
        • ex) this_snake_case
      • PascalCase
        • 모든 단어가 대문자로 시작
        • UpperCamelCase, CapWords라고 불리기도 함
        • 파이썬에서는 클래스를 명명할 때 사용
        • ex) ThisPascalCase
      • camelCase
        • 처음은 소문자로 시작하고 이후의 모든 단어의 첫 글자는 대문자
        • 파이썬에서는 거의 사용하지 않습니다 (Java 등에서 사용)
        • ex) thisCamelCase

좋은 웹페이지 즐겨찾기