-
Notifications
You must be signed in to change notification settings - Fork 3
Session1/erun1012 #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| ## 1. 컴프리헨션 문법 | ||
| > 파이썬의 자료구조 데이터를 **간결하게** 생성할 수 있는 문법 | ||
|
|
||
| ### 리스트 컴프리헨션 | ||
| > 리스트를 만드는 간결한 방법을 제공 | ||
|
|
||
| ```python | ||
| numbers = [] | ||
| for i in range(5): | ||
| numbers.append(i*2) | ||
|
|
||
| #컴프리헨션 표현 | ||
| numbers = [i*2 for i in range(5)] | ||
| # [0, 2, 4, 6, 8] | ||
|
|
||
| #조건문을 넣어도 됨 | ||
| even = [i for i in range(10) if i % 2 == 0] | ||
| # [0, 2, 4, 6, 8] | ||
|
|
||
| #if 중첩도 가능 | ||
| data = [i for i in range(1,11) if i % 2 == 0 if i<5] | ||
| # [0, 2, 4] | ||
| ``` | ||
|
|
||
| ```python | ||
| date = [(x,y) for x in range(1,6) for y in range(1,4)] | ||
|
|
||
| # for 문과 비교 | ||
| date2 = [] | ||
| for i in range(1,6): | ||
| for j in range(1,4): | ||
| data2.append((i,j)) | ||
|
|
||
| # [(1, 1), (1, 2), (1, 3), | ||
| # (2, 1), (2, 2), (2, 3), | ||
| # (3, 1), (3, 2), (3, 3), | ||
| # (4, 1), (4, 2), (4, 3), | ||
| # (5, 1), (5, 2), (5, 3)] | ||
| ``` | ||
|
|
||
| ### 딕셔너리 컴프리헨션 | ||
|
|
||
| **유의할 점 : for문 앞에 키:값을 적는다는 것과 대괄호가 중괄호로 바뀐 것** | ||
|
|
||
| ```python | ||
| squares = [x: x**2 for x in range(5)] | ||
| # {0:0, 1:1, 2:4, 3:9, 4:16} | ||
| ``` | ||
|
|
||
| zip 함수 결합 | ||
| ```python | ||
| name = ["왕춘삼", "김덕팔", "황갑득"] | ||
| age = [23, 14, 42] | ||
|
|
||
| data = {key: value for (key, value) in zip(name, age) if value > 20} | ||
|
|
||
| # 출력결과 | ||
| {'왕춘삼': 23, '황갑득': 42} | ||
| ``` | ||
|
|
||
| ### 셋(집합) 컴프리헨션 | ||
|
|
||
| **유의할 점 : 딕셔너리 컴프리헨션과 비슷, 키:값 형태가 아닌 것만 유의** | ||
|
|
||
| ```python | ||
| unique = {x%3 for x in range(10)} | ||
| # {0, 1, 2} | ||
| ``` | ||
|
|
||
| - 반복문 + 조건문을 한 줄로 표현가능 | ||
| - 가독성과 효율성 향상 | ||
| - **단, 복잡한 로직은 가독성을 해침** | ||
|
|
||
|
|
||
| 참고 문서 | ||
| https://tibetsandfox.tistory.com/25 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| ## 2. 언패킹(Unpacking)과 제너레이터(Generator) | ||
|
|
||
| ### 언패킹 | ||
| > 여러 값을 한 번에 변수에 풀어 넣는 기능 | ||
|
|
||
| ```python | ||
| a, b, c = [1, 2, 3] | ||
| print(a,b,c) | ||
| # 1 2 3 | ||
|
|
||
| #리스트나 튜플 등 반복 가능한 객체면 다 가능 | ||
| numbers = [1, 2, 3, 4, 5] | ||
| first, *middle, last = numbers | ||
| print(first, middle, last) | ||
| # 1 {2,3,4}, 5 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 실제로 이렇게 나오나요? |
||
| ``` | ||
|
|
||
| ### 제너레이터 | ||
| >데이터를 필요할 때만 하나씩 생성하는 지연평가 방식 함수 | ||
| ```python | ||
| def count_up_to(n): | ||
| for i in range(1,n+1): | ||
| yield i | ||
|
|
||
| for num in count_up_to(5): | ||
| print(num) | ||
| #1, 2, 3, 4, 5 | ||
| ``` | ||
| 함수 안에 yield 키워드를 사용하면 제너레이터이다. | ||
| yield가 값을 생성(반환)하고, 함수의 상태는 유지된 채 중단되었다가 | ||
| 다음 호출로 그 지점에서 재개된다. | ||
|
|
||
| yield 키워드 | ||
| ```python | ||
| def func(): | ||
| yield 1 | ||
| yield 2 | ||
| yield 3 | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| foo = func() | ||
|
|
||
| print(next(foo)) # 1 | ||
| print(next(foo)) # 2 | ||
| print(next(foo)) # 3 | ||
| ``` | ||
| ### return 과의 차이점 | ||
|
|
||
| 제너레이터 함수는 yield 를 통해 값을 반환. | ||
| next 메소드나 for문 순회 등을 통해 값들을 리턴받을 수 있음. | ||
| **yield가 호출된다고 해서 함수가 종료되는 것은 아님** | ||
|
|
||
| 제너레이터 내부에서 return을 사용하면 현재 값에 상관없이 StopIteration 예외 발생 | ||
|
|
||
| ```python | ||
| def func(): | ||
| print("1 리턴 전") | ||
| yield 1 | ||
| print("1 리턴 후, 2 리턴 전") | ||
| yield 2 | ||
| print("2 리턴 후, 3 리턴 전") | ||
| yield 3 | ||
| print("3 리턴 후") | ||
|
|
||
|
|
||
| foo = func() | ||
|
|
||
| print(next(foo)) | ||
| print(next(foo)) | ||
| print(next(foo)) | ||
|
|
||
| 1 리턴 전 | ||
| 1 | ||
| 1 리턴 후, 2 리턴 전 | ||
| 2 | ||
| 2 리턴 후, 3 리턴 전 | ||
| 3 | ||
| ``` | ||
|
|
||
|
|
||
| 표현식 : 리스트 컴프리헨션과 동일하지만 **[] 대신 () 사용** | ||
| -> 값을 즉시 모두 만들지 않음 | ||
|
|
||
| ```python | ||
| lst=[x*2 for x in range(5)] | ||
| gen=(x*2 for x in range(5)) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. list(gen) # [0, 2, 4, 6, 8] |
||
| ``` | ||
|
|
||
| - 전체 시퀀스를 메모리에 올리지 않음 -> 큰 파일, 로그, 스트리밍 데이터 처리에 적합 | ||
| - 필요할 때만 계산 -> 파이프라인에서 불필요한 계산 회피 | ||
| - 로컬 변수로 상태를 유지하면서 반복 로직 구현 가능 | ||
| - **디버깅 복잡, 한 번만 소비 가능. 다시 쓰려면 재생성** | ||
|
|
||
| 참고 문서 | ||
| https://tibetsandfox.tistory.com/28 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| ## 매직 메서드 | ||
| > 클래스에 특수 동작을 정의하는 메서드 (자동 호출됨) / `__이름__` 형식 | ||
|
|
||
| - `__str__` vs `__repr__` | ||
|
|
||
| ```python | ||
| class User: | ||
| def __init__(self, name): | ||
| self.name = name | ||
|
|
||
| def __str__(self): | ||
| return f"User: {self.name}" # print()용 | ||
|
|
||
| def __repr__(self): | ||
| return f"User(name='{self.name}')" # 개발자용 (디버깅) | ||
|
|
||
| user = User("Gahee") | ||
| print(user) # User: Gahee | ||
| user # User(name='Gahee') | ||
| ``` | ||
|
|
||
| → print(user) → `__str__` 호출 | ||
|
|
||
| → user → `__repr__` 호출 : 대화형 콘솔 or Jupyter 등 | ||
|
|
||
| → repr(user) → 명시적으로 `__repr__` 호출 | ||
|
|
||
| → str(user) → 명시적으로 `__str__` 호출 | ||
|
|
||
| → `__str__` 가 없으면 자동으로 `__repr__` 사용 | ||
|
|
||
|
|
||
| - `__eq__` (== 비교 연산자 오버라이드) | ||
|
|
||
| ```python | ||
| class Point: | ||
| def __init__(self, x, y): | ||
| self.x, self.y = x, y | ||
|
|
||
| def __eq__(self, other): | ||
| return self.x == other.x and self.y == other.y | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. __eq__를 구현하면 왜 __hash__도 필요할까?set이나 dict의 키로 사용할 때 어떤 문제가 생길까요? |
||
|
|
||
| p1 = Point(1, 2) | ||
| p2 = Point(1, 2) | ||
| print(p1 == p2) # True | ||
| ``` | ||
|
|
||
| → a == b 를 하면, 내부적으로 호출 | ||
|
|
||
| → 클래스에 `__eq__`를 안 만들면 ==는 ‘객체가 같은 메모리 주소를 가리키는지’ 비교 | ||
|
|
||
| - `__add__` : a + b 를 하면 내부적으로 실행 | ||
| - `__len__` : len() 실행하면 내부에서 진짜 리스트의 길이를 반환 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| ## 데코레이터(Decorator) | ||
| > 어떤 함수를 인자로 받아 꾸며준 후 다시 함수로 리턴하는 함수 | ||
| > 함수 내부에 변화 주지 않고 로직을 추가하고 싶을 때 사용 | ||
| **데코레이터는 꾸며주는 함수 내부에 직접적 수정이나 로직 변환 불가** | ||
|
|
||
| ```python | ||
| def hello(): | ||
| print("안녕!") | ||
|
|
||
| def decorator(func): | ||
| def wrapper(): | ||
| print("함수 실행 전") | ||
| func() | ||
| print("함수 실행 후") | ||
| return wrapper | ||
|
|
||
| decorated = decorator(hello) | ||
| decorated() | ||
|
|
||
| # 함수 실행 전 | ||
| # 안녕! | ||
| # 함수 실행 후 | ||
| ``` | ||
| 어떤 함수를 데코레이터로 꾸며주려면 그 함수의 선언부 위에 @데코레이터명을 적어주면 됨 | ||
| @ 문법으로 더 깔끔하게 | ||
|
|
||
| ```python | ||
| def decorator(func): | ||
| def wrapper(): | ||
| print("시작") | ||
| func() | ||
| print("끝") | ||
| return wrapper | ||
|
|
||
| @decorator | ||
| def greet(): | ||
| print("안녕 파이썬!") | ||
|
|
||
| greet() | ||
|
|
||
| # 시작 | ||
| # 안녕 파이썬! | ||
| # 끝ㅁ | ||
| ``` | ||
|
|
||
| 예시 추가 | ||
| ```python | ||
| def say_hello(): | ||
| print("Hello") | ||
|
|
||
| def decorator(func): | ||
| def sentence(*args, **kwargs): | ||
| print("Nice to meet you") | ||
| return func(*args, **kwargs) | ||
|
|
||
| return sentence | ||
|
|
||
| @decorator | ||
| def say_hello(): | ||
| print("Hello") | ||
|
|
||
| say_hello() | ||
|
|
||
| # 실행 결과 | ||
| Nice to meet you | ||
| Hello | ||
| ``` | ||
|
|
||
| 데코레이터 동작 파악 | ||
| ```python | ||
| def decorator(func): #1 | ||
| def sentence(*args, **kwargs): #3 | ||
| print("Nice to meet you") #6 | ||
| return func(*args, **kwargs) #7 | ||
|
|
||
| return sentence #4 | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. functools.wraps에 대해 좀 더 찾아보면 좋을 것 같아요. |
||
| @decorator #3 | ||
| def say_hello(): #2 | ||
| print("Hello") #8 | ||
|
|
||
|
|
||
| say_hello() #5 | ||
| ``` | ||
| #1 decorator 함수를 선언 | ||
| #2 say_hello 함수 선언 | ||
| #3 say_hello 함수를 decorator 함수로 꾸며줌. 이는 variable = decorator(say_hello)와 동일함. 따라서 sentence 함수도 이때 선언 | ||
| #4 decorator 함수로 꾸며주었기에 say_hello 함수는 sentence 함수의 로직을 실행 | ||
| #5 say_hello 함수 실행 | ||
| #6 say_hello 함수는 sentence 함수의 로직을 가지고 있기 때문에 sentence 함수의 로직 실행 | ||
| #7 decorator로 꾸며준 함수인 say_hello 함수를 호출하여 리턴 | ||
| #8 호출된 say_hello 함수가 실행 | ||
|
|
||
| class와 함께 사용도 가능 | ||
| ```python | ||
| class Decorator: | ||
| def __init__(self, func): # 꾸며줄 함수를 매개변수로 전달 | ||
| self.func = func # 꾸며줄 함수를 속성에 저장 | ||
|
|
||
| def __call__(self, *args, **kwargs): | ||
| print("Nice to meet you") | ||
| self.func() #속성에 저장된 함수 호출 | ||
| print(f"My name is {args[0]}") | ||
|
|
||
|
|
||
| @Decorator | ||
| def say_hello(): | ||
| print("Hello") | ||
|
|
||
|
|
||
| say_hello("Fox") | ||
|
|
||
| #실행 결과 | ||
| Nice to meet you | ||
| Hello | ||
| My name is Fox | ||
| ``` | ||
|
|
||
| - 코드의 중복을 최소화하고 재사용성을 높일 수 있음 | ||
| - 가독성 높일 수 있음. 로직 수정이 필요할 때도 데코레이터만 수정하면 됨 | ||
| - **중첩해서 사용하면 디버깅 난이도 상승** | ||
|
|
||
| 참고문서 | ||
| https://tibetsandfox.tistory.com/10 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오타가 있어서 실행이 안될 것 같아요