1주차 - Python (4)

35567 단어 goormgoorm

Python Programming

2022-01-06 (목)

파이썬의 모듈과 패키지에 대해서 수업을 진행하였다.
학부연구생과 석사때 하나의 .py 파일에 함수, 데이터 로드, 훈련 코드 등... 구현한 기억이 있다. 이러한 결과는 추 후에 프로젝트 내용을 정리할때 혼란이 온적이 있다. 물론, 그 당시에도 모듈에 대한 지식은 있었다.

결과 내는것에 급했기 때문에 하나의 코드 파일에 때려박았다.

개발은 혼자 진행할 때도 있지만, 팀들과 같이 개발을 하는 것이 일반적이기 때문에 각 함수들의 기능을 모듈별로 구분하여 남들도 보기 쉬운 가시성을 높여야 한다.


Lecture 9: Module & Packages

만약 다른 파일의 함수를 가지고 오고 싶다면?

  • 다른 사람이 완성한 함수와 클래스 사용.
  • 내장 & 외부 라이브러리 사용.

=> 모듈화가 필요

1. Import

  • 파이썬에선 ( 모듈 == .py 파일) 과 같다.
  • Import 구문을 사용하여 모듈을 불러옴.
import directory.functions # 폴더내 .py 파일
print(directory.functions.add(1,2))

import directory.functions as func # as로 별칭 만들기
print(func.add(1,2))

from directory.functions import add # 특정 함수 import
print(add(1,2))

from directory.functions import * # '*'로 모든 import는 권장하지 않음. 
print(add,1,2)
  • 최상위에선 상대 경로가 작동되지 않음.
    1. 최상위를 거치는 경우 포함.
    2. 일반적으로 프로젝트 이름으로 폴더를 만들어 코드를 넣음.
    3. 부모 폴더 접근을 위해서는 모듈 형태로 실행 필요.
      python -m Project_name.dir1.main
  • __init__.py 파일 폴더 import시 초기화 가능.

2. Packages

random (난수 관련 라이브러리), time (시간 관련 라이브러리), threading (쓰레드 관련 라이브러리)

파이썬은 강력하고 다양한 표준 라이브러리를 가지고 있음.

  • 파이썬 표준 라이브러리로 해결할 수 없다면? -> 외부 라이브러리 사용.

    1. 수치 그래프 그리기 (matplotlib)
    2. 웹 서버 만들기 (flask)
    3. GPU 연산 사용하기 (cupy)
    4. 딥러닝 전용 라이브러리 (tensorflow & pytorch)
  • 웹 서버 프로젝트와 딥러닝 프로젝트가 따로 있다면?

    1. 패키지 관리자가 필요 ( anaconda3, miniconda, miniforge[필자가 사용 중.] )

Lecture 10: Advanced Data Structure

  • 파이썬에는 기본적으로 몇 가지 자료구조가 사전에 선언됨. list, set, dict 등등..

  • 좀 더 강력한 자료구조를 사용하고 싶다면?

    1. 기존 자료 구조를 활용.
    2. Python Standard Library로 대부분 해결가능.
      • Stack & Queue
      • Linked List
      • Defaultdict
      • Counter
      • Named Tuple
      • Dataclass

Python Standard Library

Stack

  • 스택 구조는 기존 List를 활용. 선입후출
  • 동적 배열이기 때문에 pushpop이 O(1).
a = [1, 10]
a.append(4)
>>> [1, 10, 4]
a.append(20)
>>> [1, 10, 4, 20]
a.pop()
>>> [1, 10, 4]
a.pop()
>>> [1, 10]

Queue

  • 큐 구조 구현을 위해선 Linked List 자료 구조가 필요.
  • 양쪽으로 자유로운 입출력.
  • 중간 참조는 오래 걸리나, 큐 구조에선 상관 없음.

파이썬 collection Library의 deque를 사용!

이중 연결 리스트의 함수를 지원 left나 right에서 pop, append 가능.

from collections import deque
queue = deque([10, 5, 12])
queue.appendleft(16)
queue.pop()
>>> 12

queue.append(20)
queue.popleft()
>>> 16

queue
>>> deque([10, 5, 20])
deque(reversed(queue))
>>>deque([20, 5, 10])

Defaultdict

  • 파이썬 기본 dictionary는 Key가 없을 경우 에러가 발생함.
  • 에러 발생을 막기 위해선 get 메소드의 default 값 지정 필요.
d = {"first": 0}
d["second"]
>>> Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'second􏳐

d.get("second", "없어요")
>>> '없어요'
  • Defaultdict를 이용하면 dictionary의 기본 값을 지정 가능.
from collections import defaultdict

text = """
~~ 문장 ~~
~~ 문장 ~~
"""

characters = defaultdict(int) # 기본값 int()

for char in text:
  characters[char] += 1

Counter

  • Dictionary 처럼 생성 및 관리
from collections import Counter
c = Counter({"Korean" : 2, "English" : 3})
c.keys()
>>> Dict_keys(['korean', 'English']) # 일반적인 dict과 차이 없음.
c.values()
>>> Dict_values([2,3])
  • 집합 연산 지원
from collections import Counter
a = Counter([1, 1, 2, 2, 2, 3])
b = Counter([2, 3, 3, 4])

a+b # 횟수 더하기
>>> Counter({2: 4, 3: 3, 1: 2, 4: 1})
a & b # 교집합
>>> Counter({2: 1, 3: 1})
a | b # 합집합
>>> Counter({2: 3, 1: 2, 3: 2, 4: 1})
a - b # 차집합
>>> Counter({1: 2, 2: 2})

Named Tuple

NamedTuple 사용 X

  • 데이터만을 담기 위한 클래스 사용.
    1. 클래스 선언 및 getter 작성 필요.
    2. 숫자로 Indexing 불가능. (__getitem__ 작성 필요)

=> 간단한 데이터 구조를 굳이 클래스로 할 필요가 없음.

NamedTuple 사용 O

  • 각 튜플 원소에 이름 붙이기 가능.
  • 클래스가 아닌 튜플이기에 Unpacking 가능.
from collections import namedtuple

Coords3D = namedtuple("Coords3D", ['x','y','z'])

point = Coords3D(10,20, z= 30)
print(point.x)
>>> 10
print(point[1])
>>> 20
print(*point)
>>> 10 20 30

Dataclass

  • Pythonic한 데이터 클래스를 위해선 dataclassesdataclass 데코레이터 활용.
from dataclasses import dataclass

@dataclass
class Coords3D:
    x: float
    y: float
    z: float = 0
    def norm(self) -> float:
        return (self.x ** 2 + self.y ** 2 + self.z ** 2) ** .5

point = Coords3D(10, 20, z=30)
print(point)
>>> Coords3D(x=10, y=20, z=30)
print(point.norm())
>>> 37.416573867739416

Lecture 11: String

파이썬 String의 특징.

  • 원시 자료형이자, 불변 타입.
  • Indexing 및 Slicing이 가능함.
  • in & not in 연산이 가능.

Special Characters

Raw String

  • r"<'text'>" 형태로 \ 를 무시하고 문자 그대로 취급 가능.
  • 주로 정규 표현식에서 사용.
string = "여기서는 역 슬래시는 \n 특별한 의미를 가져요"
print(string)
>>> 여기서는 역 슬래시는 
    특별한 의미를 가져요

raw_string = r"여기서는 역 슬래시는 \n 특별한 의미를 가져요"
print(raw_string)
>>>여기서는 역 슬래시는 \n 특별한 의미를 가져요

String Functions

함수 형태기능
len(string)문자 개수 반환
string.upper()대문자로 변환
string.lower()소문자로 변환
string.capitalize()문자열 시작 문자를 대문자로 변환
string.title()단어 시작을 대문자로 변환
string.strip()좌우 공백 제거
string.lstrip()왼쪽 공백 제거
string.rstrip()오른쪽 공백 제거
string.isdigit()숫자 형태인지 확인 (True of False)
string.isupper()대문자로만 이루어져 있는지 확인 (True of False)
string.islower()소문자로만 이루어져 있는지 확인 (True of False)
string.count(pattern)문자열 string 내에 pattern 등장 횟수 반환
string.find(pattern)문자열 string 내에 pattern 첫 등장 위치 반환 (앞에서 부터)
string.rfind(pattern)문자열 string 내에 pattern 첫 등장 위치 반환 (뒤에서 부터)
string.startswith(pattern)문자열 string이 pattern으로 시작하는지 확인 (True of Flase)
string.endswith(pattern)문자열 string이 pattern으로 끝나는지 확인 (True of Flase)
string.split()공백을 기준으로 문자열 나누기
string.split(pattern)pattern을 기준으로 문자열 나누기
string.join(iterable)string을 중간에 두고 iterable 원소들 합치기

String Formatting

  • print등을 할 때 보기 좋게 값들을 확인하고 싶음.
  1. %-formating

    • %datatype %variables 형태로 표현.
    • C나 java에서 주로 쓰이는 방식.
    • "%[padding]datatype" 형태로 패딩 가능.
    • "%[padding].[precision]datatype" 형태로 정확도 지정 가능.
    • "{0}".format(variables) 형태로 표현. (순서 설정)
    • "%([name])format" 형태
    %datatype설명
    %s문자열 (str)
    %d정수 (int)
    %f부동소수점 (float)
    %o8진수
    %x16진수
print("Art: %5d, Price per Unit: %8.2f" % (453, 59.058))
>>> Art:   453, Price per Unit:    59.06
  1. F-string (필자가 자주 쓰는 포맷팅 방법)

    • f"{variable}" 형태로 표현.
    • Python 3.6이상 부터 지원
    • 변수 위치에 원하는 변수를 위치하면 됨
a, b, c = 10, 1.725, 'sample'
print(f"{a}: {b} - {c}")
>>> '10: 1.725 - sample'

문자열에서 #%Something# 을 찾거나 치환하는 방법에 사용.

  • Find 메소드는 정확히 일치하는 문자열에 대해서만 찾을 수 있음.
  • 문자열에서 특정한 패턴을 정의하고 찾는 방법이 필요. -> 정규 표현식

Regular Expression: 정규 표현식

  • 특정한 규칙을 가진 문자열의 집합을 표현하는데 사용하는 형식 언어.
  • 많은 텍스트 편집기와 프로그래밍 언어에서 문자열 검색과 치환에 활용.

정규 표현식 공부하는 것은 언어 하나를 더 배우는 것 만큼 문법이 매우 방대함.
자주 쓰이고 경험으로 터득하는 것이 좋을 것 같음.

  • 일반 텍스트 패턴
    • 정확히 일치되는 문자열 찾음.
    • .find 함수와 동일.
  • 특수 문자
    • 정규식만에서 쓰이는 문자
    • 공백, 영단어 등 일반 문자와 섞어 씀.
  • 메타 문자
    • 정규식의 문법적인 요소를 담당하는 문자 . ^ $ * + ? { }[ ] \ | ( )
    • 위의 문자들은 특수한 의미의 문자이므로, 문자 그대로 매칭하고 싶다면 Escape 문자 \ 붙여 사용.
  • 문자 클래스 [ ]
    • [ 와 ] 사이의 문자들 중 하나와 매칭
    • " - " 를 사용하여 범위를 지정 가능.
    • [^a-z],[^A-Z0-9],[^\s]
  • 부정 ^
    • [^ 와 ] 사이에 없는 문자를 매칭.
  • 문자 .
    • 아무 문자나 하나를 매칭.
    • 줄바꿈 문자 \n는 제외.
  • 0회 이상 *
    • 앞의 문자를 0개 이상 포함.
    • ab*c abbc, abbbbc -> b 0개 이상 포함.
  • 1회 이상 +
    • 앞의 문자를 1개 이상 포함.
  • 0 또는 1회 ?
    • 앞의 문자가 없을 수도 있음.
  • 반복 횟수 지정 {m,n}
    • m번 이상 n이하 반복.
    • 숫자가 하나만 주어졌을 경우.
      -> {m} : m번 반복
      -> {m,} : m번 이상 반복
      -> {,n} : n번 이하 반복.
  • Lazy Matching ?
    • * + {} 와 같은 반복 연산은 욕심이 있음 -> 최대한 길게 반복함.
    • 최대한 짧게 매칭하기 위해선 뒤에 ? 삽입.
      -> *?, +?, {m,n}?
  • 선택 |
    • 여러 식 중 하나를 선택.
  • 단어 경계 \b
    • 단어의 경계 지점인지 확인.
  • 줄의 시작 ^
    • 줄이나 문자열의 시작점.
    • Multiline flag 필요.
  • 줄의 끝 $
    • 줄이나 문자열의 .
    • Multiline flag 필요.
  • 그룹 캡쳐 ( )
    • 괄호이므로 우선 순위가 있음.
    • 해당 문자열을 캡쳐.
    • 캡쳐된 텍스트를 불러올 수 있음. \1, \2, \3, ..., \[number]
  • 비 그룹 캡쳐 (?: )
    • 괄호이므로 우선 순위가 있음.
    • 캡쳐를 하지 않음.
    • 그저 괄호..
  • 뒷 패턴 확인 D(?=R)
    • R이 바로 뒤에 있는 D를 매칭.
    • R 부분은 포함되지 않음.
  • 앞 패턴 확인 (?<=R)D
    • R이 바로 앞에 있는 D를 매칭.
    • R 부분은 포함되지 않음.

파이썬 표준 re 패키지를 사용

import re
string = \
"""
~~ 문장 ~~
~~ 문장 ~~
"""
pattern = r'~~ 패턴 ~~' # 패턴이 raw string이어야 함.
# 처음 매칭되는 문자열 탐색
match = re.search(pattern, string, re.MULTILINE)

# 모든 매칭되는 문자열 탐색
for match in re.finditer(pattern, string, re.MULTILINE):
    print(match.group(0))

# 매칭되는 패턴 치환
repl = r"치환됨-\1"
print(re.sub(pattern, repl, string, flags=re.MULTILINE)) 

# 매칭되는 패턴을 기준으로 나누기
splited = re.split(pattern, string, flags=re.MULTILINE) 
print(splited)

정규 표현식을 평가하는 것은 오래 걸림 -> 정규 표현식을 미리 컴파일 하면 훨씬 빠름.

compiled = re.compile(pattern, flags=re.MULTILINE)

for string in dataset:
	match = compiled.search(string) 
  print(match.group(0))

좋은 웹페이지 즐겨찾기