-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIterators
More file actions
148 lines (148 loc) · 5.81 KB
/
Copy pathIterators
File metadata and controls
148 lines (148 loc) · 5.81 KB
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
Data Processing:
Processing Sequential Data:
Iterators:
A container can provide an iterator that provides access to its elements in some order
iter(iterable): Return an iterator over the elements of an iterable value
next(iterator): Return the next element in an iterator
>>> d = {'one': 1, 'two': 2, 'three': 3}
>>> d
{'three': 3, 'two': 2, 'one': 1}
>>> k = iter(d)
>>> next(k)
'three'
>>> next(k)
'two'
>>> v = iter(d.values())
>>> next(v)
3
>>> next(v)
2
>>> d.pop('two')
2
>>> d
{'three': 3, 'one': 1}
The For Statement:
1. Evaluate the header expression, which must evaluate to an iterable object
2. For each element in that sequence, in order:
A. Bind name to that element in the first frame of the current environment
B. Execute the suite
When executing a for statement, iter returns an iterator and next provides each item
>>> counts = [1, 2, 3] >>> counts = [1, 2, 3]
>>> items = iter(counts) >>> for item in counts:
>>> try: print(item)
while True:
item = next(items)
print(item)
except StopIteration:
pass # Do nothing
A StopIteration exception is raised whenever next is called on an empty iterator
>>> def contains(a, b):
ai = iter(a)
for x in b:
while next(ai) != x:
pass # do nothing
return True
>>> contains('strength', 'stent')
True
Built-in Functions for Iteration:
Many built-in Python sequence operations return iterators that comput results lazily
map(func, iterable): Iterate over func(x) for x in iterable
filter(func, iterable): Iterate over x in iterable if func(x)
zip(first_iter, second_iter): Iterate over co-indexed (x, y) pairs
reversed(sequence): Iterate over x in a sequence in reverse order
To view the contents of an iterator, place the resulting elements into a container
list(iterable): Create a list containing all x in iterable
tuple(iterable): Create a tuple containing all x in iterable
sorted(iterable): Create a sorted list containing x in iterable
>>> bcd = ['b', 'c', 'd']
>>> [x.upper() for x in bcd]
['B', 'C', 'D']
>>> m = map(lambda x: x.upper(), bcd)
>>> next(m)
'B'
>>> next(m)
'C'
>>> next(m)
'D'
>>> next(m)
Error
StopIteration
Functions are applied lazily, only when asked next
>>> def double(x):
print('**', x, '=>', 2*x, '**')
return 2*x
>>> m = map(double, range(3, 7)
>>> f = lambda y: y>= 10
>>> t = filter(f, m)
>>> next(t)
** 3 => 6 **
** 4 => 8 **
** 5 => 10 **
10
>>> next(t)
** 6 => 12 **
12
>>> list(t)
[]
>>> list(filter(f, map(double, range(3, 7))))
[10, 12]
>>> t = [1, 2, 3, 2, 1]
>>> list(reversed(t)) == t
True
Zip returns an iterator that gives each of the items
>>> d = {'a': 1, 'b': 2}
>>> items = iter(d.items()) >>> items = zip(d.keys(), d.values())
>>> next(items) >>> next(items)
('b', 2) ('b', 2)
>>> next(items) >>> next(items)
('a', 1) ('a', 1)
Generators:
A generator function is a function that can yield multiple values instead of returning them
>>> def evens(start, end):
even = start + (start % 2)
while even < end:
yield even
even += 2
>>> list(evens(1, 10))
[2, 4, 6, 8]
>>> t = evens(2, 10)
>>> next(t)
2
>>> next(t)
4
Iterable User-Defined Classes
>>> list(Countdown(5)) class Countdown:
[5, 4, 3, 2, 1] def __init__(self, start):
>>> for x in Countdown(3): self.start = start
print(x) def __iter__(self):
3 v = self.start
2 while v > 0:
1 yield v
v -= 1
Generators & Iterators
A yield from statement yields all values from an iterator or iterable
>>> list(a_then_b([3, 4], [5, 6]))
[3, 4, 5, 6]
>>> def a_then_b(a, b): def a_then_b(a, b):
for x in a: yield from a
yield x yield from b
for x in b:
yield x
>>> def countdown(k):
if k > 0:
yield k
yield from countdown(k-1)
else:
yield 'Blast off'
>>> def prefixes(s):
if s:
yield from prefixes(s[:-1])
yield s
>>> list(prefixes('both'))
['b', 'bo', 'bot', 'both']
>>> def substrings(s):
if s:
yield from prefixes(s)
yield from substrings(s[1:])
>>> list(substrings('tops'))
['t', 'to', 'top', 'tops', 'o', 'op', 'ops', 'p', 'ps', 's']