Skip to content

Commit b2d29e3

Browse files
committed
Create Standard Library.md
1 parent ed39f9f commit b2d29e3

File tree

1 file changed

+300
-0
lines changed

1 file changed

+300
-0
lines changed

docs/Standard Library.md

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
# **Standard Library**
2+
3+
Python이 기본 제공하는 모듈들
4+
5+
## **1. collections**
6+
Python의 `collections` 모듈은 다양한 데이터 구조를 쉽게 다룰 수 있도록 도와줌.
7+
8+
Counter, defaultdict, deque, OrderedDict, namedtuple 등이 자주 사용된다.
9+
10+
### 1.1 **collections.Counter (요소 개수 세기)**
11+
리스트 요소의 개수를 쉽게 세는 기능.
12+
13+
#### dict 사용
14+
```python
15+
words = ["apple", "banana", "apple", "cherry", "banana", "apple"]
16+
word_count = {}
17+
for word in words:
18+
if word in word_count:
19+
word_count[word] += 1
20+
else:
21+
word_count[word] = 1
22+
print(word_count)
23+
```
24+
25+
- dict를 사용하면 키가 존재하는지 매번 확인해야 하므로 코드가 복잡하고 비효율적.
26+
27+
#### collections.Counter 사용
28+
```python
29+
from collections import Counter
30+
31+
words = ["apple", "banana", "apple", "cherry", "banana", "apple"]
32+
word_count = Counter(words)
33+
print(word_count)
34+
```
35+
36+
- 내부적으로 최적화되어 있어 요소 개수를 더 빠르고 간결하게 계산.
37+
38+
### 1.2 **collections.deque (빠른 리스트 연산)**
39+
앞쪽 원소 삽입/삭제 시 `list`는 O(n)이지만 `deque`는 O(1)로 동작.
40+
41+
#### 리스트 사용 (비효율적)
42+
```python
43+
lst = [1, 2, 3]
44+
lst.insert(0, 0) # O(n) 연산
45+
lst.pop(0) # O(n) 연산
46+
```
47+
48+
- list는 앞쪽 원소를 삽입/삭제할 때 모든 요소를 이동해야 하므로 O(n) 시간이 걸림.
49+
50+
#### deque 사용 (효율적)
51+
```python
52+
from collections import deque
53+
54+
dq = deque([1, 2, 3])
55+
dq.appendleft(0) # O(1)
56+
dq.popleft() # O(1)
57+
```
58+
59+
- deque는 양쪽 끝에서 O(1)로 삽입/삭제 가능하여 효율적.
60+
61+
---
62+
63+
## **2. itertools**
64+
반복 가능한 객체를 다루는 다양한 기능 제공.
65+
66+
count, cycle, chain, permutations, starmap 등을 사용하여 반복문과 조건문을 간단하고 효율적으로 처리할 수 있도록 도와준다.
67+
68+
### 2.1 **itertools.permutations (순열 조합 구하기)**
69+
70+
#### 재귀 함수 사용
71+
```python
72+
def permute(arr, path=[]):
73+
if not arr:
74+
print(path)
75+
return
76+
for i in range(len(arr)):
77+
permute(arr[:i] + arr[i+1:], path + [arr[i]])
78+
79+
permute([1, 2, 3])
80+
```
81+
82+
- 재귀 호출로 인해 비효율적이고 코드가 길어짐.
83+
84+
#### itertools.permutations 사용
85+
```python
86+
from itertools import permutations
87+
88+
arr = [1, 2, 3]
89+
perm_list = list(permutations(arr))
90+
print(perm_list)
91+
```
92+
93+
- 내부적으로 최적화되어 간결하고 빠름.
94+
95+
### 2.2 **itertools.starmap (튜플 언패킹 최적화)**
96+
`map()` 대신 사용하면 성능 향상.
97+
98+
#### 일반 map() 사용
99+
```python
100+
def add(a, b):
101+
return a + b
102+
103+
pairs = [(1, 2), (3, 4), (5, 6)]
104+
result = list(map(lambda x: add(*x), pairs))
105+
```
106+
107+
- lambda로 언패킹해야 함.
108+
109+
#### starmap() 사용
110+
```python
111+
from itertools import starmap
112+
113+
def add(a, b):
114+
return a + b
115+
116+
pairs = [(1, 2), (3, 4), (5, 6)]
117+
result = list(starmap(add, pairs))
118+
```
119+
120+
- 불필요한 lambda 호출을 줄여 성능이 향상됨.
121+
122+
## **3. functools**
123+
함수 최적화 및 고차 함수 지원.
124+
125+
lru_cache, partial, reduce, update_wrapper, total_ordering 등 여러 고차 함수들을 통해 반복적인 작업을 최적화하고, 코드의 가독성 및 재사용성을 높이는 데 유용하다.
126+
127+
### 3.1 **functools.lru_cache (재귀 최적화)**
128+
129+
#### 사용하지 않음 (느림)
130+
```python
131+
def fib(n):
132+
if n <= 1:
133+
return n
134+
return fib(n-1) + fib(n-2)
135+
136+
print(fib(30)) # 매우 느림
137+
```
138+
139+
- 동일한 값을 여러 번 재귀 호출 → 중복 계산 발생 (O(2^n))
140+
- 호출 깊이가 커질수록 기하급수적으로 느려짐
141+
142+
#### lru_cache 사용 (빠름)
143+
```python
144+
from functools import lru_cache
145+
146+
@lru_cache(maxsize=None)
147+
def fib(n):
148+
if n <= 1:
149+
return n
150+
return fib(n-1) + fib(n-2)
151+
152+
print(fib(30)) # 훨씬 빠름
153+
```
154+
155+
- 한 번 계산한 값은 캐싱 → 중복 호출 없이 O(n)
156+
- 불필요한 연산을 제거해 실행 속도 대폭 향상
157+
158+
## **4. datetime**
159+
날짜 및 시간 다루기.
160+
161+
날짜, 시간, 시간 차이, 시간대 변환 등을 손쉽게 처리할 수 있는 기능을 제공한다.
162+
163+
datetime 객체의 메소드를 사용하면 날짜와 시간 연산을 간단하게 할 수 있으며, 다양한 형식으로 날짜와 시간을 출력하거나 변환할 수 있다.
164+
165+
### 4.1 **datetime.datetime (시간 정보 가져오기)**
166+
167+
#### time 사용
168+
```python
169+
import time
170+
171+
timestamp = time.time()
172+
year = 1970 + timestamp // (365 * 24 * 3600)
173+
print(f"현재 연도: {int(year)}")
174+
```
175+
176+
- Unix 타임스탬프를 직접 변환 → 연도 계산이 번거롭고 가독성 낮음
177+
178+
#### datetime 사용
179+
```python
180+
from datetime import datetime
181+
182+
now = datetime.now()
183+
print(f"현재 연도: {now.year}")
184+
```
185+
186+
- 즉시 연도 반환
187+
188+
## **5. pathlib**
189+
파일 시스템 경로 다루기.
190+
191+
pathlib는 파일 경로를 다루는 다양한 메소드를 제공한다. 예를 들어, joinpath()로 경로를 이어 붙이거나, stem, suffix와 같은 속성을 이용해 파일명이나 확장자도 쉽게 다룰 수 있다.
192+
193+
또한 운영 체제에 맞는 경로 구분자를 자동으로 처리한다. 즉, Windows에서는 백슬래시(\), UNIX-like 시스템에서는 슬래시(/)를 자동으로 다루어 주므로, 플랫폼에 상관없이 코드가 안정적으로 실행된다.
194+
195+
### 5.1 **pathlib.Path (파일 존재 여부 확인)**
196+
197+
#### os 사용
198+
```python
199+
import os
200+
201+
filepath = "example.txt"
202+
if os.path.exists(filepath):
203+
print("파일 존재함")
204+
```
205+
206+
- 문자열 경로 처리
207+
208+
#### pathlib.Path 사용
209+
```python
210+
from pathlib import Path
211+
212+
filepath = Path("example.txt")
213+
if filepath.exists():
214+
print("파일 존재함")
215+
```
216+
217+
- Path 객체 사용 → 경로 조작이 직관적이고 가독성 향상
218+
219+
## **6. array**
220+
메모리 효율적인 배열 사용.
221+
222+
메모리 절약, 인덱스 접근 속도 향상 등의 장점도 있지만 데이터 타입을 고정해야 하므로, 서로 다른 데이터 타입을 저장할 수 있는 리스트보다 유연성이 떨어진다.
223+
224+
### 6.1 **array.array**
225+
226+
#### 리스트 사용 (비효율적)
227+
```python
228+
lst = [1, 2, 3, 4, 5] # 객체 포인터 저장
229+
```
230+
231+
- 객체 포인터 저장 → 메모리 사용량 증가
232+
233+
#### array 사용 (효율적)
234+
```python
235+
from array import array
236+
237+
arr = array('i', [1, 2, 3, 4, 5]) # 'i'는 정수(int) 타입 지정
238+
```
239+
240+
- 연속된 메모리 블록 사용 → 메모리 절약, 성능 향상
241+
242+
## **7. 병렬 처리**
243+
244+
### 7.1 **multiprocessing (CPU 병렬 처리)**
245+
246+
#### 단일 프로세스 실행 (느림)
247+
```python
248+
def work(n):
249+
return sum(i*i for i in range(n))
250+
251+
nums = [10**6, 10**6, 10**6, 10**6]
252+
results = [work(n) for n in nums] # 한 개씩 실행 (느림)
253+
```
254+
255+
- 한 번에 하나씩 처리 → CPU 코어 활용 부족
256+
257+
#### multiprocessing 사용 (빠름)
258+
```python
259+
from multiprocessing import Pool
260+
261+
def work(n):
262+
return sum(i*i for i in range(n))
263+
264+
nums = [10**6, 10**6, 10**6, 10**6]
265+
with Pool() as pool:
266+
results = pool.map(work, nums) # 병렬 실행 (빠름)
267+
```
268+
269+
- 여러 코어에서 병렬 실행 → 실행 속도 향상
270+
271+
### 7.2 **concurrent.futures.ThreadPoolExecutor (I/O 최적화)**
272+
273+
#### 단일 스레드 실행 (느림)
274+
```python
275+
import requests
276+
277+
urls = ["https://example.com"] * 10
278+
279+
for url in urls:
280+
response = requests.get(url)
281+
print(response.status_code)
282+
```
283+
284+
- 한 번에 하나씩 처리 → I/O 작업에 시간이 많이 소요됨
285+
286+
#### ThreadPoolExecutor 사용 (빠름)
287+
```python
288+
from concurrent.futures import ThreadPoolExecutor
289+
import requests
290+
291+
urls = ["https://example.com"] * 10
292+
293+
with ThreadPoolExecutor() as executor:
294+
results = executor.map(requests.get, urls)
295+
296+
for response in results:
297+
print(response.status_code)
298+
```
299+
300+
- 여러 스레드에서 병렬 실행 → I/O 대기 시간 동안 다른 요청 처리 가능, 속도 향상

0 commit comments

Comments
 (0)