-
Notifications
You must be signed in to change notification settings - Fork 0
/
generators.py
61 lines (49 loc) · 1.69 KB
/
generators.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
'''
Generator functions are a special kind of function that return a lazy iterator:
Iterator is an object returning items one-by-one instead of all at once (like a list)
and the generator function is paused until the next item is requested.
However, unlike lists, lazy iterators do not store their contents in memory.
-> List: fast but heavy
-> Generators: slow but light
'''
import sys
import time
numbers = range(0, 10000, 1)
# list comprehension
start_time = time.time()
lc = [n*n for n in numbers if n % 2 == 1] # list comprehension
time.time() - start_time
lc # lc produces a list object => created AND iterated at once
type(lc)
print(sys.getsizeof(lc)) # bytes
# generator comprehension
start_time = time.time()
ge = (n*n for n in numbers if n % 2 == 1)
time.time() - start_time
ge # ge produces a generator object => created AND iterated at each iteration (lazy approach)
type(ge)
print(sys.getsizeof(ge)) # bytes
for i in ge:
print(i)
for i in ge:
print(i) # ge exausted during first iteration and no more available
'''
yield statement suspends function execution and returns the yielded value to the caller.
In contrast, return stops function execution completely.
When a function is suspended, the state of that function is saved.
This includes any variable bindings local to the generator,
the instruction pointer, the internal stack, and any exception handling.
next() resumes function execution where it was yielded.
'''
def cmap(funcs, arr):
for f in funcs:
output = list(map(f, arr))
arr = output
# return output
yield output # generator
funcs = [lambda x: x*x, lambda x: x+x]
arr = [1, 2, 3, 4]
result = cmap(funcs, arr)
#print(result)
next(result)
next(result)