22
33So far we have used for loops with many different kinds of things.
44
5- ``` py
5+ ``` python
66>> > for name in [' theelous3' , ' RubyPinch' , ' go|dfish' ]:
77... print (name)
88...
@@ -24,7 +24,7 @@ over the list `['a', 'b', 'c']`. If we can iterate over something, then
2424that something is ** iterable** . For example, strings and lists are
2525iterable, but integers and floats are not.
2626
27- ``` py
27+ ``` python
2828>> > for thing in 123 :
2929... print (thing)
3030...
@@ -38,7 +38,7 @@ TypeError: 'int' object is not iterable
3838
3939Lists and strings don't change when we iterate over them.
4040
41- ``` py
41+ ``` python
4242>> > word = ' hi'
4343>> > for character in word:
4444... print (character)
@@ -54,7 +54,7 @@ We can also iterate over [files](../basics/files.md), but they remember
5454their position and we get the content once only if we iterate over them
5555twice.
5656
57- ``` py
57+ ``` python
5858>> > with open (' test.txt' , ' w' ) as f:
5959... print (" one" , file = f)
6060... print (" two" , file = f)
7777We have also used [ enumerate] ( ../basics/trey-hunner-zip-and-enumerate.md )
7878before, and it actually remembers its position also:
7979
80- ``` py
80+ ``` python
8181>> > e = enumerate (' hello' )
8282>> > for pair in e:
8383... print (pair)
@@ -109,7 +109,7 @@ Iterators have a magic method called `__next__`, and there's a built-in
109109function called ` next() ` for calling that. Calling ` next() ` on an
110110iterator gets the next value and moves it forward. Like this:
111111
112- ``` py
112+ ``` python
113113>> > e = enumerate (' abc' )
114114>> > e.__next__ ()
115115(0 , ' a' )
@@ -122,7 +122,7 @@ iterator gets the next value and moves it forward. Like this:
122122
123123There's also a built-in ` next() ` function that does the same thing:
124124
125- ``` py
125+ ``` python
126126>> > e = enumerate (' abc' )
127127>> > next (e)
128128(0 , ' a' )
@@ -137,7 +137,7 @@ Here `e` remembers its position, and every time we call `next(e)` it
137137gives us the next element and moves forward. When it has no more values
138138to give us, calling ` next(e) ` raises a StopIteration:
139139
140- ``` py
140+ ``` python
141141>> > next (e)
142142Traceback (most recent call last):
143143 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
150150StopIteration. That's actually what for looping over an iterator does.
151151For example, this code...
152152
153- ``` py
153+ ``` python
154154for pair in enumerate (' hello' ):
155155 print (pair)
156156```
157157
158158...does roughly the same thing as this code:
159159
160- ``` py
160+ ``` python
161161e = enumerate (' hello' )
162162while True :
163163 try :
@@ -178,7 +178,7 @@ Now we know what iterating over an iterator does. But how about
178178iterating over a list or a string? They are not iterators, so we can't
179179call ` next() ` on them:
180180
181- ``` py
181+ ``` python
182182>> > next (' abc' )
183183Traceback (most recent call last):
184184 File " <stdin>" , line 1 , in < module>
@@ -189,7 +189,7 @@ TypeError: 'str' object is not an iterator
189189There's a built-in function called ` iter() ` that converts anything
190190iterable to an iterator.
191191
192- ``` py
192+ ``` python
193193>> > i = iter (' abc' )
194194>> > i
195195< str_iterator object at 0x 7f987b860160>
@@ -208,7 +208,7 @@ StopIteration
208208
209209Calling ` iter() ` on anything non-iterable gives us an error.
210210
211- ``` py
211+ ``` python
212212>> > iter (123 )
213213Traceback (most recent call last):
214214 File " <stdin>" , line 1 , in < module>
@@ -219,7 +219,7 @@ TypeError: 'int' object is not iterable
219219If we try to convert an iterator to an iterator using ` iter() ` we just
220220get back the same iterator.
221221
222- ``` py
222+ ``` python
223223>> > e = enumerate (' abc' )
224224>> > iter (e) is e
225225True
@@ -228,14 +228,14 @@ True
228228
229229So code like this...
230230
231- ``` py
231+ ``` python
232232for thing in stuff:
233233 print (thing)
234234```
235235
236236...works roughly like this:
237237
238- ``` py
238+ ``` python
239239iterator = iter (stuff)
240240while True :
241241 try :
@@ -254,7 +254,7 @@ much simpler way to implement iterators. Let's make a function that
254254creates an iterator that behaves like ` iter([1, 2, 3]) ` using the
255255` yield ` keyword:
256256
257- ``` py
257+ ``` python
258258>> > def thingy ():
259259... yield 1
260260... yield 2
@@ -266,7 +266,7 @@ creates an iterator that behaves like `iter([1, 2, 3])` using the
266266We can only ` yield ` inside a function, yielding elsewhere raises an
267267error.
268268
269- ``` py
269+ ``` python
270270>> > yield ' hi'
271271 File " <stdin>" , line 1
272272SyntaxError : ' yield' outside function
@@ -275,7 +275,7 @@ SyntaxError: 'yield' outside function
275275
276276Let's try out our thingy function and see how it works.
277277
278- ``` py
278+ ``` python
279279>> > thingy()
280280< generator object thingy at 0x b723d9b4>
281281>> >
@@ -290,7 +290,7 @@ iterators** with some more features that we don't need to care about.
290290
291291The generator we got works just like other iterators:
292292
293- ``` py
293+ ``` python
294294>> > t = thingy()
295295>> > t
296296< generator object thingy at 0x b72300f4>
@@ -318,7 +318,7 @@ the yields, when do they run? How does Python know when to run what?
318318
319319Let's find out.
320320
321- ``` py
321+ ``` python
322322>> > def printygen ():
323323... print (" starting" )
324324... yield 1
@@ -336,7 +336,7 @@ That's weird! We called it, but it didn't print "starting"!
336336
337337Let's see what happens if we call ` next() ` on it.
338338
339- ``` py
339+ ``` python
340340>> > got = next (p)
341341starting
342342>> > got
@@ -354,7 +354,7 @@ still there just like they were when we left.
354354A similar thing happens here. Our function is running, but it's just
355355stuck at the yield and waiting for us to call ` next() ` on it again.
356356
357- ``` py
357+ ``` python
358358>> > next (p)
359359between 1 and 2
3603602
@@ -382,7 +382,7 @@ for loops work.
382382that making a list of them would be too slow or the list wouldn't fit in
383383the computer's memory. So instead of this...
384384
385- ``` py
385+ ``` python
386386def get_things ():
387387 result = []
388388 # code that appends things to result
@@ -391,22 +391,22 @@ def get_things():
391391
392392...we can do this:
393393
394- ``` py
394+ ``` python
395395def get_things ():
396396 # code that yields stuff
397397```
398398
399399Both of these functions can be used like this:
400400
401- ``` py
401+ ``` python
402402for thing in get_things():
403403 # do something with thing
404404```
405405
406406It's actually possible to create an iterator that yields an infinite
407407number of things:
408408
409- ``` py
409+ ``` python
410410>> > def count ():
411411... current = 1
412412... while True :
0 commit comments