🔎 파이썬
1. 리스트 커프리헨션
일반적인 for루프를 사용해 리스트를 만드는 방식보다 더 간단하게 표현 가능
squares = [x**2 for x in range(1,6)] #x에 간단한 수식을 넣고 for문을 통해 x에 1부터 6까지의 수를 넣음
print(squares) #[1, 4, 9,16, 25]
even_squares = [x**2 for x in range(1,11) if x % 2 == 0]
#x에 식을 정한 뒤 for문을 통해 x에 1~10까지 넣고 if문으로 짝수만 넣은 것이다.
combinations = [(x, y) for x in [1,2,3] for y in [4, 5,6]]
#x,y를 변수로 정한 뒤 for문으로 x와y에 각각 넣을 수를 넣어준 것이다
2. 이터레이터
- 복잡한 제어가 필요할 떄 유용
- 파이썬의 순차적 데이터 처리 도구
- 반복가능한 객체 내부에서 값을 하나씩 꺼내서 제공하는 객체
- __iter__() 객체 자신을 반환한다.
- __next__()메서드는 호출될 때마다 이터레이터의 다음 값을 반환하며 반한 값이 없을 경우 StopIteration 예외를 발생
classs MyIterator: #클래스 정의
def __init__(self, max_value):
#init은 클래스의 생성자로 객체가 생성될 때 호출 된다.
#max_value라는 인자를 받아서 이터레이터가 몇 번까지 값을 생성할지 설정한다.
self.current = 0 #현재 이터레이터가 어느 위치에 있는지 저장하며 처음은 0으로 설정했다.
self.max_value = max_value #이터레이터가 생성할 수 있는 최대값
# 이터레이터 객체를 반환하는 메서드로 이 메서드를 통해 이터레이터로 사용할 수 있는 객체가 반환
# 이 함수는 클래스 자체를 반환하여 이 클래스가 이터레이터로 동작할 수 있게 한다.
def __iter__(self):
return self
# 이터레이터의 다음 값을 반환하는 메서드
#__next__()는 반복할 때마다 호출되며, 이 메서드가 없으면 이터레이터로 사용할 수 없다
def__next__(self):
if self.current < self.max_value: # 현재 값이 최대 값보다 작을 때 다음 값을 반환 합니다.
self.current += 1 #현재 값을 1씩 증가 시킴니다.
return self.current # 증가 된 값을 반환한다
else:
raise StopIteration #위의 if 조건에 맞지 않을 때 예외를 발생 시켜 동작을 멈춘다.
3. 제너레이터
- 간단하게 이터레이션할 때 유용
- 이터레이터의 특별한 형태
- 주로 yield키워드를 사용해 만들며 값을 하나씩 반환하고 그 상태를 기억한 후 다음 호출시 그 다음 값을 반환합니다.
- 제너레이터는 return이 아닌 yield를 사용해 값을 반환하기 때문에 함수를 끝내지 않고도 여러번 호출이 가능
def infinite_sequence(): #무한수열 함수 지정
num = 0 #첫 시작 0 지정
while True: #조건이 True일 때 반복
yield num #num을 반환 값으로 지정
num += 1 #반환할 때 1씨증가 지정
gen = infinite_sequence() #지정함수를 gen으로 지정
for val in gen: #for문으로 val에 gen 지정 / 왜자꾸 새로운 이름으로 바꾸면서 진행하는 것인가? 가독성과 유연성 향상
if val > 5: #val이 5보다 클때 지정
break # 위 조건일 때 동작 멈춤
print(val)
4. Python GIL (강의 한번 들어 봐야할 듯)
- CPython 인터프리터에서 사용하는 메커니즘으로, 여러 스레드가 동시에 Python 객체에 접근하는 것을 방지하고 한 번에 하나의 스레드만 Python 바이트코드를 실행할 수 있도록 제어하는 역할
- Python이 메모리 관리를 안전하게 수행하기 위한 방편
- 스레드: 프로세스 내부에서 일어나는 작은 작업단위
5. Python 코루틴
- 일반함수와 유사하지만 실행 중에 중단하고 다시 재개할 수있는 특별한 함수
- 비동기적 프로그래밍을 지워하며, 주로 비동기 I/O작업에서 효율적인 방식으로 사용
- 시간이 오래걸리는 작업을 기다리지 않고 작업 수행가능
- 함수 내에서 yield 또는 await 키워드를 사용하여 정의
- 데이터를 주고 받는 방식으로 동작
import asyncio
import aiohttp #비동기 HTTP 라이브러리 import
#async def는 비동기 함수(코루틴)을 정의할 때 사용
async def fetch(session, url):
print(f"Fetching: {url}") #작동 시작 전 출력 메세지
async with session.get(url) as response:#주어진 url에 대한 요청을 보내기
return await response.text() #비동기적으로 응답내용을 가져온다.
#여러 url을 비동기적으로 처리하는 메인 코루틴
async def fetch_all(urls):
async with aiohttp.ClientSession() as session: #http 요청을 보내기 위한 세션 객체 생성
tasks = [fetch(session, url) for url in urls]
results = await asyncio.gather(*tasks) #모든 코루틴을 동시에 실행
return results
urls = [
'https://www.example.com',
'https://www.python.org',
'https://www.github.com'
]
#비동기 작업 실행
async def main():
results = await fetch_all(urls)
for i, result in enumerate(results): #enumerate함수를 이용하여 인덱스(i)와 값(result)을 반환
print(f"Result from {urls[i]}: {result[:100]}...")
asyncio.run(main()) #비동기 작업을 실행하기 위한 이벤트 루프
6. 비동기적 I/O작업
- 네트워크 통신 / 파일 입출력 / 데이터베이스 호출에 유용
- 데이터를 읽고 쓰는 동안 프로그램이 다른 작업을 할 수 있도록 허용하는 방식입니다.
- I/O 작업을 요청하고 그 작업이 완료 될 때까지 기다리는 동안 프로그램의 나머지 부분이 계속해서 실행될 수 있다.
- 흐름: 작업요청 => 다른 작업 수행 => 작업 완료 알림
7. 람다 표현식
익명의 함수를 만들기 위한 방식
함수를 한 줄로 표현할 때 유용
함수의 인자를 넘기거나 리스트 항목 정렬에 유용
1) 인자 넘기기
numbers = [1,2,3,4,5]
squared = list(map(lambda x: x**2, numbers))
#lambda를 이용해 x의 제곱을 구하는 식을 너고 인자로 numbers를 가져온다.
print(squared)
[1, 4, 9, 16, 25]
2) 리스트 정렬
point = [(1,2,3), (3,1,5), (5,7,2), (2, 3, 6)]
#key로 lambda한수 적용 => 튜플에 첫번째 값을 기준으로 정렬
#두번째나 세번째를 기준으로 잡고 싶을 땐 point[1]이나 point[2]로 할 수 있다.
point_sorted = sorted(point, key=lambda, point: point[0])
print(point_sorted)
[(1, 2, 3), (2, 3, 6), (3, 1, 5), (5, 7, 2)]