Python_1 - jjin-choi/study_note GitHub Wiki
Β§ Intro
- κ°μ¬λͺ : κΉμ μΈ
- email : [email protected]
- github : https://github.com/imguru-mooc/python_intermediate
- Ref : νμ΄μ¬ μλ²½ κ°μ΄λ / Python Cookbook (λ°μ΄λΉλ M. λΉμ¦λ¦¬)
Β§ ν¨μμ ν¨μν νλ‘κ·Έλλ°
1. νμ΄μ¬ ν¨μμ νΉμ§
3 def add(x, y):
4 return x+y
5
6 a= add(3, 4)
7 print (a)
8 print (type(add))
9 print (add)
- output
- line 7 ) 7
- line 8 ) <class 'function'>
- line 9 ) <function add at 0x7f682f067e18>
11 import sys
12 sys.getrefcount(add)
13
14 add1 = add
15 a = add1(3, 4)
16
17 print(type(add1))
18 print (add1)
19 sys.getrefcount(add)
- add1 κ³Ό add μ μ£Όμκ°μ΄ κ°λ€ β κ°μ κ°μ²΄λ₯Ό κ°λ¦¬ν€κ³ μμ
- sys.getrefcount λ λκΉ?
- νμ΄μ¬μμλ ν¨μκ° κ°μ²΄μ΄λ€. (symbolλ‘ κ°λ¦¬ν¬ μ μλ λͺ¨λ typeμ΄ λͺ¨λ κ°μ²΄μ΄λ€.)
- ν¨μλ refcount = 0 μΌλ μμ ν μ κ±°λλ€.
2. default parameter
- μΈμλ ν¨μλ₯Ό νΈμΆνμ λ μ ν΄μ§μ§λ§, default parameterλ ν¨μ μ μ μμ μ ν΄μ§λ€.
1 a = 10
2
3 def foo(x=a):
4 return x
5
6 a = 5
7 print (foo())
- default parameterλ μ μ μ μ ν΄μ§λ©°, runtime μμμλ μ¬λΌμ§μ§ μλλ€.
10 def foo(x, items=[]):
11 items.append(x)
12 return items
13
14 print(foo(1))
15 print(foo(2))
16 print(foo(3))
- λ°λΌμ μ²μ μ μμμλ None μ΄λΌκ³ λ£κ³ , None μΌ λ μμ±νλλ‘ μμ
18 def foo(x, items=None):
19 if items is None:
20 items = []
21 items.append(x)
22 return items
23
24 print(foo(1))
25 print(foo(2))
26 print(foo(3))
3. κ°λ³ μΈμ
-
*κ° λΆμ건, python ννμ κ°λ³μΈμ (pointerκ° μλ)
-
μΈμμ *μ μ¬μ©νλ©΄ λ¨μ μλ λͺ¨λ μΈμκ° __νν__λ‘μ packingλμ΄ args λ³μμ μ μ₯λλ€.
-
ννμ κ°μ λ°κΏ μ μμ
-
ν€μλ μΈμ : foo(x=3, y=22, w='hello', z=[1,2]) λΌκ³ λ£μ΄λ x, y, w, z κ° key μν μ νμ¬ μ€μ function foo μμμ key κ°μ μ°Ύμ κ°μ λμ νλ€.
- κΈ°λ³Έ μΈμλ ν€μλ μΈμλ₯Ό μμ΄μ λ£μ μ μμ
- νμ§λ§ κΈ°λ³Έ μΈμλ μμλλ‘ λ€μ΄κ°κΈ° λλ¬Έμ λ€μ λ¨μ ν€μλ μΈμλ μμμμ κΈ°λ³Έ μΈμλ₯Ό λ€μ μ€μ ν΄μ€ μ μλ€.
-
**κ° λΆμΌλ©΄, κ°λ³ ν€μλ μΈμλΌκ³ νλ€.
-
κ°λ³ ν€μλ μΈμλ __λμ λ리__λ‘μ μ μ₯νλ€.
- %> parms.pop("fgcolor", "black") : fgcolor μ defaultλ black μ΄κ³ κ°μ΄ λ€μ΄μ€λ©΄ κ·Έ κ°μΌλ‘.
1 def make_table(data, **params):
2 fgcolor = params.pop("fgcolor", "black")
3 bgcolor = params.pop("bgcolor", "white")
4 width = params.pop("width", None)
5
6 print (fgcolor)
7 print (bgcolor)
8 print (width)
9
10 if params:
11 raise TypeError (f"Unsupported configuration options {list(params)}")
12
13 items = [1, 2, 3]
14 make_table(items, fgcolor="red", bgcolor="black", border=1)
4. ν€μλ 맀κ°λ³μλ§ λ°λ ν¨μ
1 def recv(maxsize, *, block=True):
2 print (maxsize, block)
3
4 recv(8192, block=False) # Work
5
6 try:
7 recv(8192, False) # Fail
8 except TypeError as e:
9 print (e)
10
11
12 def minimum(*values, clip=None):
13 m = min(values)
14
15 if clip is not None:
16 m = clip if clip > m else m
17 return m
18
19 print (minimum(1, 5, 2, -5, 10))
20 print (minimum(1, 5, 2, -5, 10, clip=0))
- python μμλ call by reference μ΄λ―λ‘ ν¨μ λ΄μμ κ° λ³κ²½ μ μλ κ°μ²΄ κ°μλ λ°μλλ€.
- β» m = clip if clip > m else m
- β» for I, x in enumerate(items)
- μ¬λ¬ κ°μ return νλ©΄ ννμ λ£μ΄μ 1κ°μ κ°μΌλ‘ return λλ€.
5. μ ν¨ λ²μ (scope)
- μ μ λ³μ aκ° μκ³ ν¨μ λ΄λΆa κ° μμ λ ν¨μ λ΄λΆμ aλ ν¨μμ μν μ§μ λ³μ
- ν¨μ λ΄μμ global aμ μ¬μ©νλ©΄, μ μ λ€μμ€νμ΄μ€ aλ₯Ό μλ―Ένλ€.
1 a = 42
2 b = 37
3
4 def foo():
5 global a
6 a = 13
7 b = 0
8
9 foo()
10 print (f"a = {a}, b = {b}")
- nested ν¨μ (μ€μ²© ν¨μ) μμ λ³μμ μ΄λ¦μ μ΄ν μ ν¨ λ²μμ λ°λΌ μ°Ύμ μ§λ€.
- μ¦ μ€μ²© ν¨μ λ΄μμ λ³μκ° μμΌλ©΄ νμΉΈ λ°μΌλ‘ λκ°μ λ³μ λ₯Ό μ°Ύλλ€.
- νμ§λ§ λ°κΉ₯μͺ½ ν¨μμμ μ μλ μ§μ λ³μ κ°μ μμͺ½ ν¨μμμ λ€μ ν λΉν μλ μλ€.
- unboundLocalError : local variable 'n' referenced before assignment
- κ·Έλ°λ° ! λ°κΉ₯μͺ½ ν¨μμμ μ μλ μ§μ λ³μ κ°μ μμͺ½ ν¨μμμ λ€μ ν λΉνλ λ°©λ²μ΄ μλ€.
- λ°λ‘ nonlocal μ μ¬μ©νλ©΄ λλ€.
- nonlocal μ μκΈ° scope λ°μ κ°μ₯ κ°κΉμ΄ λ°κΉ₯μͺ½ ν¨μμμ μ μλ μ§μ λ³μλ₯Ό λ¬Άλλ€.
12 #----------------------------------------
13 def countdown(start):
14 n = start
15 def display():
16 print (f'T-minus {n}')
17
18 while n > 0:
19 display()
20 n -= 1
21
22 countdown(3)
23 #----------------------------------------
24
25 def countdown(start):
26 n = start
27 def display():
28 print (f'T-minus {n}')
29
30 def decrement():
31 n -= 1
32
33 while n > 0:
34 display()
35 decrement() # Error
36
37 countdown(3)
38 #----------------------------------------
39 def countdown(start):
40 n = start
41 def display():
42 print (f'T-minus {n}')
43
44 def decrement():
45 nonlocal n
46 n -= 1
47
48 while n > 0:
49 display()
50 decrement() # Error
51
52 countdown(3)
6.lambda ν¨μ
- lambda λ 1μ€ ν¨μμ΄λ€. λ€λ₯Έ νλ‘κ·Έλλ° μΈμ΄μμλ μ΅λͺ ν¨μλΌκ³ λ λΆλ₯Έλ€.
- νλ‘κ·Έλ¨ λ΄μμ ν¨μλ₯Ό μ¬μ¬μ© νμ§ μμΌλ €λ κ²½μ° lambda ν¨μλ₯Ό μΈ μ μλ€.
- μΌλ° ν¨μμ ννλ λΉμ·νκ³ λΉμ·νκ² μλ.
- format : lambda (μΈμ) : (return)
1 add = lambda x, y : x + y
2 # μλ ν¨μμ λμΌ
3 # def add(x, y):
4 # return x + y
- μΈμ μ°λ©΄ νΈν κΉ?
- sorting ν λ μ¬μ©νλ©΄ νΈνλ€.
8 a = [(1, 2), (4, 1), (9, 10), (13, -3)]
9 a.sort(key=lambda x: x[1])
10 print (a)
11 # sort by second value
- μ£Όμμ¬ν
- λλ€μμ μ¬μ©ν x κ°μ΄ μ€ν μκ°μ λ¬λΌμ§λ λ³μμ΄λ€.
- default parameterκ° μλλΌ μ μ λ³μμΌ λΏμ΄λ€.
- ν¨μλ₯Ό μ μν λ νΉμ κ°μ κ³ μ νκ³ μΆμΌλ©΄, λν΄νΈ parameterλ‘ μ§μ νλ©΄ λλ€.
14 x = 10
15 a = lambda y : x + y
16 x = 20
17 b = lambda y : x + y
18
19 print ("\nlambda function1")
20 print (a(10)) # output : 30
21 print (b(10)) # output : 30
22
23 #----------------------------------------
24 x = 10
25 a = lambda y, x=x : x + y
26 x = 20
27 b = lambda y, x=x : x + y
28
29 print ("\nlambda function2")
30 print (a(10)) # output : 30
31 print (b(10)) # output : 30
-
list comprehension
- ex) func = [lambda x: x+n for n in range(5)]
- β func = [lambda x, n=n : x+n for n in range(5)]
- n κ°μ΄ λ³ν κ²μ΄λΌκ³ κΈ°λ νμ§λ§ λλ€ ν¨μλ κ°μ₯ λ§μ§λ§ κ°μ μ¬μ©νλ€.
- n κ°μ ν¨μλ₯Ό μ μνλ μμ μ κ°μΌλ‘ κ³ μ ν΄λκ³ μ¬μ©νλ€.
-
ν¨μ μΈμμ meta data λ£κΈ°
- ex) def add(x:int, y:int) -> int:
- help(add) νΉμ add.annotations μ΄μ©ν΄μ λ³Ό μ μμ
- μΈμμ μ 보λ₯Ό μΆκ°ν΄μ λ€λ₯Έ μ¬λμ΄ ν¨μλ₯Ό μ΄λ»κ² μ¬μ©νλμ§ μ μ μλλ‘ νλ€.
- ν¨μμ μ£Όμμ ν¨μμ __annotations__μ μ μ₯λλ€.
7.closure
- closure
- closure λ?
- ν¨μκ° λ°μ΄ν°λ‘ μ·¨κΈλ λλ ν¨μκ° μ μλ κ³³μ μ£Όλ³ νκ²½ μ λ³΄κ° ν¨κ» μ μ₯λλ€.
- ν¨μκ° return ν λ μκΈ° λ΄λΆμ μλ ν¨μλ₯Ό νΈμΆνλ κ²½μ°
- ν¨μλ₯Ό ꡬμ±νλ λ¬Έμ₯κ³Ό μ€ν νκ²½μ ν¨κ» λ¬Άμ κ²μ closure λΌκ³ νλ€.
- μ΄ μμμμλ mul_add κ° closure, μΈν리 μμ μλ κ° μ΄λΌλ μλ―Έ
- ν¨μλ₯Ό ν λ² νΈμΆνλ©΄ κ·Έ μμ closure κ° κ³μ μ μ§λλ©° λ€μ νΈμΆ μ λ λ€λ₯Έ closure κ° μμ±λλ€.
- closure λ΄λΆμ closure μ free variable (μ§μ λ³μ) μ΄ μ μ₯λμ΄ μλ€.
1 def calc():
2 a = 3
3 b = 5
4
5 def mul_add(x):
6 return a * x + b
7 return mul_add
8
9 c = calc()
10 print (c(1), c(2), c(3), c(4))
11
12
13 print (c.__closure__)
14 print (c.__closure__[0].cell_contents)
15 print (c.__closure__[1].cell_contents)
- ꡬνμ΄ κ°λ¨ν μμμΈ κ²½μ° λλ€λ₯Ό μ΄μ©νμ¬ ν΄λ‘μ λ₯Ό μ¬μ©ν μ μλ€. λ΄λΆ ν¨μλ₯Ό μ§μ νΈμΆν μΌμ΄ μμΌλ―λ‘ μ΄λ¦μ΄ μμ΄λ λλ€.
18 def calc():
19 a = 3
20 b = 5
21
22 return lambda x: a * x + b
23
24 c = calc()
25 print (c(1), c(2), c(3), c(4))
26
27
28 print (c.__closure__)
29 print (c.__closure__[0].cell_contents)
30 print (c.__closure__[1].cell_contents)
31
- ν΄λ‘μ λ΄λΆμμ μ μν λ³μμ μ κ·Όλ κ°λ₯νλ€.
- nonlocal μ μΈμΌλ‘ λ΄λΆ λ³μλ₯Ό μμ νλ ν¨μλ₯Ό μμ±
- μ κ·Ό λ©μλλ₯Ό ν΄λ‘μ ν¨μμ λΆμ¬ λ§μΉ μΈμ€ν΄μ€ λ©μλμΈ κ²μ²λΌ λμνλ κ²
- nμ κ°μ closureμ λ€μ΄μκ³ , propertyμ ν¨μλ€μ dict ννλ‘ μ μ₯λμ΄ μλ€.
33 def sample():
34 n = 0
35
36 def func():
37 print ('n = ', n)
38
39 def get_n():
40 return n
41
42 def set_n(value):
43 nonlocal n
44 n = value
45
46 func.get_n = get_n
47 func.set_n = set_n
48 return func
49
50
51 if __name__ == '__main__':
52 f = sample()
53 f()
54
55 n = 0
56 f.set_n(10)
57
58 f()
59 print(f.get_n())
8. decorator
- μ΄ μμμμλ func μ΄ μ§μλ³μ, μ¦ closureμ νκ²½μ΄ λλ€.
- make_func_alarm μμ func μ΄λΌλ μΈμκ° λ€μ΄μ€λλ°, μ΄ ν¨μ νΈμΆμ΄ λλλ©΄ func μ μ¬λΌμ§μ§λ§ closure μλ λ¨μμλ€.
- λ°λΌμ ν¨μλ₯Ό μΈμλ‘ λ°μμ, ν¨μ μ νμ μλ‘μ΄ κΈ°λ₯μ μΆκ°ν ν¨μλ₯Ό λ§λ€ μλ μλ€. !
- make_func_alarm μ΄ decorator κ° λλ€.
1 def big_number(n):
2 return n ** n ** n
3
4 def make_func_alarm(func):
5
6 def new_func(*args, **kwargs):
7 print (" function start ! ")
8 result = func(*args, **kwargs)
9 print (" function end ! ")
10 return result
11
12 return new_func
13
14 new_func = make_func_alarm(big_number)
15 new_func(6)
- μ¬κΈ°μ line 14 μ line 15 κ° λ²κ±°λ‘λ€.
- μμ μλ closureλ₯Ό λ°μμ λ€μ νλ² νΈμΆν΄μ€μΌ νλ λ²κ±°λ‘μμ΄ μμ΄, python μμλ μ΄λ₯Ό μλμΌλ‘ ν΄μ£Όλ macro κ° μλ€.
- @λ₯Ό μ¬μ©νμ !
- @make_time_checker λ¬Έλ²μ decorator
- make_time_checker λΌλ ν¨μμλ€κ° big_numberλ₯Ό λκΈ΄ νν
- μ¦ μ΄λ€ ν¨μ μμͺ½μ @__ λ₯Ό μ¨μ€λ€λ κ²μ, κ·Έ ν¨μλ₯Ό decoratorμ λκ²¨μ£Όκ² λ€λ μλ―Έ.
- μ€μ λ‘λ μ μ½λμ λμΌν μν μ ν΄μ€λ€.
1 import time
2
3 def make_func_checker(func):
4
5 def new_func(*args, **kwargs):
6 start_time = time.perf_counter()
7 result = func(*args, **kwargs)
8 end_time = time.perf_counter()
9 print ("runtime : ", end_time - start_time)
10 return result
11 return new_func
12
13 @make_func_checker
14 def big_number(n):
15 return n ** n ** n
16 # big_number = make_time_checker(big_number)
17 big_number(7)
- Tracer tool (μ΄λ€ ν¨μκ° νΈμΆλμλμ§ λ€ λ‘κ·Έλ‘ λ¨κΈ°κ³ μΆμ λ)
- enable_tracing μ True / False λ‘ ν΄λμ΄, tracing μ ν μ§ λ§μ§λ₯Ό κ²°μ ν μ μλ€.
- μ§κΈμ μ¬μ©λ² μ λλ§.. !
1 enable_tracing = True
2
3 if enable_tracing:
4 debug_log = open("debug.log", "w")
5
6 def trace(func):
7 if enable_tracing:
8 def callf(*args, **kwargs):
9 debug_log.write("\n\n--------------------------------------------")
10 debug_log.write(f"\nCalling {func.__name__} : {args} {kwargs}\n")
11 r = func(*args, **kwargs)
12 debug_log.write(f"{func.__name__} returned {r}\n")
13 debug_log.write("--------------------------------------------\n\n")
14
15 return r
16 return callf
17 else:
18 return func
19
20 @trace
21 def square(x):
22 return x * x
23
24 square(100)
9. Iterator
- λ°λ³΅μ : μν κ°λ₯ν μμ΄ν
μ μ κ·Όν λ for μνλ¬Έμ μ¬μ©νκ³ μΆμ§ μλ€λ©΄ !? iterator μ¬μ©νλ©΄ λλ€.
- with : context manager (λμ€μ 곡λΆνκΈ°λ‘..)
- nextλ iterator λ₯Ό μ¬μ©νμμ.
- μ΄ μμ μμλ λ μ΄μ nextλ₯Ό ν μ μμ λ μμΈκ° λ°μνκ² λκ³ μ΄ λ StopIteration
1 with open("debug.log") as f : # f = open("passwd")
2 try:
3 while True:
4 line = next(f)
5 print(line)
6 except StopIteration:
7 pass
- ν¨μ iter (iteratorμ μ½μ)
- it λ python μμλ reference (cμμλ pointer) κ° λλ€.
- iterμ list μ΄λ file μ΄λ μ΄λ€ containerκ° μ€λ μ§ sequential νλ©΄ μμ°¨μ μΌλ‘ μ΄λνλ reference κ° λλ©° μ΄κ² κ°λ₯ν containerλ₯Ό iterable container λΌκ³ λΆλ₯΄λ©° μ€μ λ‘ μ΄λνλ μ΄ referenceλ₯Ό iterator λΌκ³ λΆλ₯Έλ€.
10 items = [1, 2, 3] # list
11 it = iter(items) # print (it) : <list_iterator object at ...>
12 print (next(it))
13 print (next(it))
14 print (next(it))
10. Delegating μν
- [func] : special function
- μλ μμμμ root Node μ _children listμ κ°κ° child1 child2 λ₯Ό append νλ€.
- python μμλ tree λΌλ κ΅¬μ‘°μ²΄κ° μκΈ° λλ¬Έμ μ΄λ₯Ό list λ‘ κ°μ§κ³ λ§λ€μ΄ μ€ κ²
- for ch in root μ΄λ, μλ μ£Όμμ²λ¦¬λ whileλ¬Έκ³Ό λμΌνλ€
- λν print (κ°μ²΄) μ΄λ κ² ν΄μ£Όλ©΄, κ°μ²΄μ addressκ° λμ€λ―λ‘ Node ν¨μ λ΄μλ repr ν¨μλ₯Ό λ§λ€μ΄, κ°μ νμν΄μ£Όλ ν¨μλ₯Ό λ§λ€μ΄μ£Όμλ€.
1 class Node:
2 def __init__(self, value):
3 self._value = value
4 self._children = []
5
6 def __repr__(self):
7 return f'Node({self._value})'
8
9 def add_child(self, node):
10 self._children.append(node)
11
12 def __iter__(self):
13 # iter(n1) == n1.__iter__()
14 return iter(self._children)
15
16
17 if __name__ == '__main__':
18 root = Node(0)
19 child1 = Node(1)
20 child2 = Node(2)
21
22 root.add_child(child1)
23 root.add_child(child2)
24
25 for ch in root:
26 print (ch) # to print out _value, Node has __repr__ function
27
28 # --- for loop ---
29 # it = iter(root)
30 # while True:
31 # ch = next(it)
32 # print (ch)
11. Generator
- ν¨μ κ°μ²΄μ yield (μ보νλ€) λΌλ μμ½μ΄κ° νλλΌλ μλ€λ©΄ generator μ΄λ€.
- xμ κ°μ λμ Έμ£Όλ©΄μ μ보νλ€..
- yield λ return κ³Ό κ°μ§λ§ ν¨μκ° λλ κ²μ μλλ€. ν¨μμ μ μ΄κΆμ νΈμΆμμκ² μ보νλ€.
- yield κ° μλ ν¨μλ μΌλ° ν¨μκ° μλλΌ generator μ΄κΈ° λλ¬Έμ c = countdown(3) μ΄λΌκ³ νλ©΄ generator κ°μ²΄λ₯Ό λ겨주λ κ².
- next λ₯Ό νκ² λλ©΄ yield ꡬ문κΉμ§ μνλκ³ , μ΄ λ yield κ° nμ λ겨주면μ λ©μΆλ€.
- κ·Έ λ€μ next κ° μ¬λ κΉμ§ yield μ λ©μΆ°μλ€κ° nextκ° λ λ€μ΄μ€λ μκ° yield λ€μ νλΆν° μνλλ€.
- iterator μ λμΌν λμμ νλ€. (λ€λ₯Έ μ μ, μ΄λ―Έ μλ containerμΈ list κ°μκ±Έ μννλκ² μλλΌ κ·Έ λ κ·Έ λ μμ±λλ κ°μ κ°μ§κ³ μ μ΄ μ‘°κ±΄μ νλμ© μ보νλ©΄μ ν¨μ λ°κ³Ό μμ νλνλμ© μ²λ¦¬νλ λ³ν μ²λ¦¬λ₯Ό λ§λ€ μ μλ€.
def countdown(n):
print('Starting to count from',n)
while n > 0:
yield n
n -= 1
print('Done!')
12. iterator & generator
- python μμ tree ꡬ쑰λ₯Ό μννλ €λ©΄ μ¬κ·ν¨μλ₯Ό νΈμΆν΄μΌ νλ μΆμ§λ§,
- 맨 μλμ for ch in root.depth_first(): μμλ generatorλ₯Ό κΊΌλ΄λ κ²μ΄κ³ (μλλ©΄ depth_first ν¨μμ yield κ° μμΌλ―λ‘)
- depth_first μμμ for c in self: μμλ self μ μλ listμ iterator κ° νΈμΆλλ κ².
- yield from [A] μ [A] μ μλ iterator μ μ΄μ©ν΄μ λμκ² μ보νλΌλ μλ―Έ
- root - left - right λ‘ μννλ pre order traverse μκ³ λ¦¬μ¦μ΄ λλ€. (root λΆν° λ°©λ¬Ένλ κ²)
1 class Node:
2 def __init__(self, value):
3 self._value = value
4 self._children = []
5
6 def __repr__(self):
7 return f' :: Node({self._value}) ::'
8
9 def add_child(self, node):
10 self._children.append(node)
11
12 def __iter__(self):
13 return iter(self._children)
14
15 def depth_first(self):
16 yield self
17 for c in self:
18 yield from c.depth_first()
19
20
21 if __name__ == '__main__':
22 root = Node(0)
23 child1 = Node(1)
24 child2 = Node(2)
25
26 root.add_child(child1)
27 root.add_child(child2)
28
29 child1.add_child(Node(3))
30 child1.add_child(Node(4))
31 child2.add_child(Node(5))
32
33 for ch in root.depth_first():
34 print (ch)
35
36 # g = root.depth_first()
37 # while True :
38 # ch = next(g)
39 # print (ch, end = '')
40 #
41 # it = iter(self)
42 # while True:
43 # ch = next(g)
13. reverse μν λ° μνλ₯Ό κ°μ§ generator
- deque λ listμ λΉμ·νμ§λ§ μΌμͺ½ μ€λ₯Έμͺ½μμ μ½μ κ°λ₯ (stack, queue λ‘λ μ¬μ©κ°λ₯)
- κ°μ²΄ μ체μ for .. in .. μ μ¬μ©νλ©΄ κ°μ²΄ λ΄λΆμ iter ν¨μλ₯Ό νκ² λλ€. (μμΌλ©΄ κΈ°λ³Έ iter ν¨μ λμ)
- generator μνλ νμ¬ line μ, max λ₯Ό κ°μ§κ³ μκ² λλ€.
30 from collections import deque
31
32 class linehistory:
33 def __init__(self, lines, histlen=3):
34 self.lines = lines
35 self.history = deque(maxlen=histlen)
36
37 def __iter__(self):
38 for lineno, line in enumerate(self.lines, 1):
39 self.history.append((lineno, line))
40 yield line
41
42 def clear(self):
43 self.history.clear()
44
45 with open('debug.log') as f:
46 lines = linehistory(f)
47
48 for line in lines:
49 if 'python' in line:
50 for lineno, hline in lines.history:
51 print (f'{lineno} : {hline}')
14. iterator & generator
- list μΈ κ²½μ° slice κ°λ₯νμ§λ§ generator λ [:] κ° λμ§ μμ (TypeError : 'generator' object is not subscriptable)
- μ΄λ₯Ό μ§μνλκ² itertools !
1 import itertools
2
3 for x in itertools.islice(c, 10, 20):
4 print (x)
- μν κ°μ²΄ 첫 λ²μ§Έ λΆλΆ 건λλ°κΈ°
1 from itertools import dropwhile
2 with open("debug.log") as f:
3 for line in dropwhile(lambda line: line.startswith('#'), f):
4 print (line)
-
enumerate(list) μ¬μ©νλ©΄ (index, value) λ₯Ό return ν΄μ€
- enumerate(list, 1) μ΄λΌκ³ νλ©΄ 1λΆν° index μμ
-
zip (x, y) λΌκ³ νλ©΄ x μ yμ λκ°μ indexλ₯Ό λμ μν
- xμ yμ κ°μκ° λ§μ§ μλ κ²½μ°μλ νμ 짧μ μͺ½μΌλ‘ μννλ€.
- λ§μ½ κΈ΄ μͺ½μΌλ‘ μννκΈ°λ₯Ό μνλ€λ©΄, zip_longest λ₯Ό μ¬μ©νλ©΄ λλ€.
6 a = [1, 2, 3]
7 b = ['w', 'x', 'y', 'z']
8
9 from itertools import zip_longest
10 for i in zip(a, b):
11 print (i)
12
13 for i in zip_longest(a, b):
14 print (i)
15. coroutine
- generator μ€ νλ
- generator μμ yieldλ μΌμͺ½μ μ무κ²λ μμ΄μ, ν¨μκ° μ΄ μ§μ μ λμ°©νλ©΄ n μ΄λΌλ κ²μ λ°λμͺ½μ μ보νκ³ μ μ΄κΆμ΄ λ©μΆμλλ°, μ½λ£¨ν΄μμλ μ¦μ μ μ΄κΆμ μ보 yieldμ λ°©ν₯μ΄ R valueλ‘ κ°μμ.
- μμμμ yield λ dataλ₯Ό λ겨주λ ꡬ쑰μλ€λ©΄, μ§κΈμ yield λ dataλ₯Ό λ°μμ£Όλ ꡬ쑰.
- λλ΄κΈ° μν΄μλ close λΌλ ν¨μκ° μμ
1 def receiver():
2 print ("Ready to receive")
3
4 while True:
5 n = yield
6 print (f"Got {n}")
7
8 r = receiver()
9 print (r)
10
11 next(r)
12 r.send(1)
13 r.send(2)
14 r.send("Hello")
- coroutine κ³Ό decorator (nextλ₯Ό μλμΌλ‘ ν΄ μ£Όλ μν ) λ₯Ό κ°μ΄ μ¨μ£Όλ©΄ μ’λ€.
- close μ΄νμλ send λ₯Ό νλ©΄ generator κ° μ΄λ―Έ stop 쑰건μ λ§λ λ€μ΄κΈ° λλ¬Έμ StopIteration μλ¬ λ°μνλ€.
16 def coroutine(func):
17 def start (*args, **kwargs):
18 g = func(*args, **kwargs)
19 next (g)
20 return g
21 return start
22
23 @coroutine
24 def receiver():
25 print ("\nReady to receive")
26 while True:
27 n = yield
28 print (f"Got {n}")
29
30 receiver()
31 r.send("coroutine with decorator")
32 r.close()
- generator μ coroutine μ ν¨κ» μ°λ©΄ pipe μν μ νκ² λλ€.
- ps -ef | grep ls | wc -l μ΄λ° pipe !
- code λ reference μμ μ°Έκ³ νκΈ° (1.16)