2
2
3
3
So far we have used for loops with many different kinds of things.
4
4
5
- ``` py
5
+ ``` python
6
6
>> > for name in [' theelous3' , ' RubyPinch' , ' go|dfish' ]:
7
7
... print (name)
8
8
...
@@ -24,7 +24,7 @@ over the list `['a', 'b', 'c']`. If we can iterate over something, then
24
24
that something is ** iterable** . For example, strings and lists are
25
25
iterable, but integers and floats are not.
26
26
27
- ``` py
27
+ ``` python
28
28
>> > for thing in 123 :
29
29
... print (thing)
30
30
...
@@ -38,7 +38,7 @@ TypeError: 'int' object is not iterable
38
38
39
39
Lists and strings don't change when we iterate over them.
40
40
41
- ``` py
41
+ ``` python
42
42
>> > word = ' hi'
43
43
>> > for character in word:
44
44
... print (character)
@@ -54,7 +54,7 @@ We can also iterate over [files](../basics/files.md), but they remember
54
54
their position and we get the content once only if we iterate over them
55
55
twice.
56
56
57
- ``` py
57
+ ``` python
58
58
>> > with open (' test.txt' , ' w' ) as f:
59
59
... print (" one" , file = f)
60
60
... print (" two" , file = f)
77
77
We have also used [ enumerate] ( ../basics/trey-hunner-zip-and-enumerate.md )
78
78
before, and it actually remembers its position also:
79
79
80
- ``` py
80
+ ``` python
81
81
>> > e = enumerate (' hello' )
82
82
>> > for pair in e:
83
83
... print (pair)
@@ -109,7 +109,7 @@ Iterators have a magic method called `__next__`, and there's a built-in
109
109
function called ` next() ` for calling that. Calling ` next() ` on an
110
110
iterator gets the next value and moves it forward. Like this:
111
111
112
- ``` py
112
+ ``` python
113
113
>> > e = enumerate (' abc' )
114
114
>> > e.__next__ ()
115
115
(0 , ' a' )
@@ -122,7 +122,7 @@ iterator gets the next value and moves it forward. Like this:
122
122
123
123
There's also a built-in ` next() ` function that does the same thing:
124
124
125
- ``` py
125
+ ``` python
126
126
>> > e = enumerate (' abc' )
127
127
>> > next (e)
128
128
(0 , ' a' )
@@ -137,7 +137,7 @@ Here `e` remembers its position, and every time we call `next(e)` it
137
137
gives us the next element and moves forward. When it has no more values
138
138
to give us, calling ` next(e) ` raises a StopIteration:
139
139
140
- ``` py
140
+ ``` python
141
141
>> > next (e)
142
142
Traceback (most recent call last):
143
143
File " <stdin>" , line 1 , in < module>
@@ -150,14 +150,14 @@ and it's best to just try to get a value from it and catch
150
150
StopIteration. That's actually what for looping over an iterator does.
151
151
For example, this code...
152
152
153
- ``` py
153
+ ``` python
154
154
for pair in enumerate (' hello' ):
155
155
print (pair)
156
156
```
157
157
158
158
...does roughly the same thing as this code:
159
159
160
- ``` py
160
+ ``` python
161
161
e = enumerate (' hello' )
162
162
while True :
163
163
try :
@@ -178,7 +178,7 @@ Now we know what iterating over an iterator does. But how about
178
178
iterating over a list or a string? They are not iterators, so we can't
179
179
call ` next() ` on them:
180
180
181
- ``` py
181
+ ``` python
182
182
>> > next (' abc' )
183
183
Traceback (most recent call last):
184
184
File " <stdin>" , line 1 , in < module>
@@ -189,7 +189,7 @@ TypeError: 'str' object is not an iterator
189
189
There's a built-in function called ` iter() ` that converts anything
190
190
iterable to an iterator.
191
191
192
- ``` py
192
+ ``` python
193
193
>> > i = iter (' abc' )
194
194
>> > i
195
195
< str_iterator object at 0x 7f987b860160>
@@ -208,7 +208,7 @@ StopIteration
208
208
209
209
Calling ` iter() ` on anything non-iterable gives us an error.
210
210
211
- ``` py
211
+ ``` python
212
212
>> > iter (123 )
213
213
Traceback (most recent call last):
214
214
File " <stdin>" , line 1 , in < module>
@@ -219,7 +219,7 @@ TypeError: 'int' object is not iterable
219
219
If we try to convert an iterator to an iterator using ` iter() ` we just
220
220
get back the same iterator.
221
221
222
- ``` py
222
+ ``` python
223
223
>> > e = enumerate (' abc' )
224
224
>> > iter (e) is e
225
225
True
@@ -228,14 +228,14 @@ True
228
228
229
229
So code like this...
230
230
231
- ``` py
231
+ ``` python
232
232
for thing in stuff:
233
233
print (thing)
234
234
```
235
235
236
236
...works roughly like this:
237
237
238
- ``` py
238
+ ``` python
239
239
iterator = iter (stuff)
240
240
while True :
241
241
try :
@@ -254,7 +254,7 @@ much simpler way to implement iterators. Let's make a function that
254
254
creates an iterator that behaves like ` iter([1, 2, 3]) ` using the
255
255
` yield ` keyword:
256
256
257
- ``` py
257
+ ``` python
258
258
>> > def thingy ():
259
259
... yield 1
260
260
... yield 2
@@ -266,7 +266,7 @@ creates an iterator that behaves like `iter([1, 2, 3])` using the
266
266
We can only ` yield ` inside a function, yielding elsewhere raises an
267
267
error.
268
268
269
- ``` py
269
+ ``` python
270
270
>> > yield ' hi'
271
271
File " <stdin>" , line 1
272
272
SyntaxError : ' yield' outside function
@@ -275,7 +275,7 @@ SyntaxError: 'yield' outside function
275
275
276
276
Let's try out our thingy function and see how it works.
277
277
278
- ``` py
278
+ ``` python
279
279
>> > thingy()
280
280
< generator object thingy at 0x b723d9b4>
281
281
>> >
@@ -290,7 +290,7 @@ iterators** with some more features that we don't need to care about.
290
290
291
291
The generator we got works just like other iterators:
292
292
293
- ``` py
293
+ ``` python
294
294
>> > t = thingy()
295
295
>> > t
296
296
< generator object thingy at 0x b72300f4>
@@ -318,7 +318,7 @@ the yields, when do they run? How does Python know when to run what?
318
318
319
319
Let's find out.
320
320
321
- ``` py
321
+ ``` python
322
322
>> > def printygen ():
323
323
... print (" starting" )
324
324
... yield 1
@@ -336,7 +336,7 @@ That's weird! We called it, but it didn't print "starting"!
336
336
337
337
Let's see what happens if we call ` next() ` on it.
338
338
339
- ``` py
339
+ ``` python
340
340
>> > got = next (p)
341
341
starting
342
342
>> > got
@@ -354,7 +354,7 @@ still there just like they were when we left.
354
354
A similar thing happens here. Our function is running, but it's just
355
355
stuck at the yield and waiting for us to call ` next() ` on it again.
356
356
357
- ``` py
357
+ ``` python
358
358
>> > next (p)
359
359
between 1 and 2
360
360
2
@@ -382,7 +382,7 @@ for loops work.
382
382
that making a list of them would be too slow or the list wouldn't fit in
383
383
the computer's memory. So instead of this...
384
384
385
- ``` py
385
+ ``` python
386
386
def get_things ():
387
387
result = []
388
388
# code that appends things to result
@@ -391,22 +391,22 @@ def get_things():
391
391
392
392
...we can do this:
393
393
394
- ``` py
394
+ ``` python
395
395
def get_things ():
396
396
# code that yields stuff
397
397
```
398
398
399
399
Both of these functions can be used like this:
400
400
401
- ``` py
401
+ ``` python
402
402
for thing in get_things():
403
403
# do something with thing
404
404
```
405
405
406
406
It's actually possible to create an iterator that yields an infinite
407
407
number of things:
408
408
409
- ``` py
409
+ ``` python
410
410
>> > def count ():
411
411
... current = 1
412
412
... while True :
0 commit comments