If you're seeing this message, it means we're having trouble loading external resources on our website.
If you're behind a web filter, please make sure that the domains *.kastatic.org and *.kasandbox.org are unblocked.
You’ll start with a comparison of some different paradigms used by programming languages to implement definite iteration.
Then you will learn about iterables and iterators, two concepts that form the basis of definite iteration in Python.
Finally, you’ll tie it all together and learn about Python’s
for in :
0 loops.Free Download: Get a sample chapter from Python Tricks: The Book that shows you Python’s best practices with simple examples you can apply instantly to write more beautiful + Pythonic code.
A Survey of Definite Iteration in Programming
Definite iteration loops are frequently referred to as
for in :
0 loops because for in :
0 is the keyword that is used to introduce them in nearly all programming languages, including Python.Historically, programming languages have offered a few assorted flavors of
for in :
0 loop. These are briefly described in the following sections.Remove adsNumeric Range Loop
The most basic
for in :
0 loop is a simple numeric range statement with start and end values. The exact format varies depending on the language but typically looks something like this:for i = 1 to 10
Here, the body of the loop is executed ten times. The variable
for in :
7 assumes the value for in :
8 on the first iteration, for in :
9 on the second, and so on. This sort of for in :
0 loop is used in the languages BASIC, Algol, and Pascal.Three-Expression Loop
Another form of
for in :
0 loop popularized by the C programming language contains three parts:- An initialization
- An expression specifying an ending condition
- An action to be performed at the end of each iteration.
This type of loop has the following form:
for [i = 1; i >> a = ['foo', 'bar', 'baz']
>>> for i in a:
... print[i]
...
foo
bar
baz
2 increments the variable for in :
7. It is roughly equivalent to >>> a = ['foo', 'bar', 'baz']
>>> for i in a:
... print[i]
...
foo
bar
baz
4 in Python.This loop is interpreted as follows:
- Initialize
7 tofor in :
8.for in :
- Continue looping as long as
7.>>> a = ['foo', 'bar', 'baz'] >>> for i in a: ... print[i] ... foo bar baz
- Increment
7 byfor in :
8 after each loop iteration.for in :
Three-expression
for in :
0 loops are popular because the expressions specified for the three parts can be nearly anything, so this has quite a bit more flexibility than the simpler numeric range form shown above. These for in :
0 loops are also featured in the C++, Java, PHP, and Perl languages.Collection-Based or Iterator-Based Loop
This type of loop iterates over a collection of objects, rather than specifying numeric values or conditions:
for i in
Each time through the loop, the variable
for in :
7 takes on the value of the next object in >>> iter['foobar'] # String
>>> iter[['foo', 'bar', 'baz']] # List
>>> iter[['foo', 'bar', 'baz']] # Tuple
>>> iter[{'foo', 'bar', 'baz'}] # Set
>>> iter[{'foo': 1, 'bar': 2, 'baz': 3}] # Dict
3. This type of for in :
0 loop is arguably the most generalized and abstract. Perl and PHP also support this type of loop, but it is introduced by the keyword >>> iter['foobar'] # String
>>> iter[['foo', 'bar', 'baz']] # List
>>> iter[['foo', 'bar', 'baz']] # Tuple
>>> iter[{'foo', 'bar', 'baz'}] # Set
>>> iter[{'foo': 1, 'bar': 2, 'baz': 3}] # Dict
5 instead of for in :
0.Further Reading: See the For loop Wikipedia page for an in-depth look at the implementation of definite iteration across programming languages.
The Python for in :
0 Loop
for in :
Of the loop types listed above, Python only implements the last: collection-based iteration. At first blush, that may seem like a raw deal, but rest assured that Python’s implementation of definite iteration is so versatile that you won’t end up feeling cheated!
Shortly, you’ll dig into the guts of Python’s
for in :
0 loop in detail. But for now, let’s start with a quick prototype and example, just to get acquainted.Python’s
for in :
0 loop looks like this:for in :
>>> iter[42] # Integer
Traceback [most recent call last]:
File "", line 1, in
iter[42]
TypeError: 'int' object is not iterable
>>> iter[3.1] # Float
Traceback [most recent call last]:
File "", line 1, in
iter[3.1]
TypeError: 'float' object is not iterable
>>> iter[len] # Built-in function
Traceback [most recent call last]:
File "", line 1, in
iter[len]
TypeError: 'builtin_function_or_method' object is not iterable
0 is a collection of objects—for example, a list or tuple. The >>> iter[42] # Integer
Traceback [most recent call last]:
File "", line 1, in
iter[42]
TypeError: 'int' object is not iterable
>>> iter[3.1] # Float
Traceback [most recent call last]:
File "", line 1, in
iter[3.1]
TypeError: 'float' object is not iterable
>>> iter[len] # Built-in function
Traceback [most recent call last]:
File "", line 1, in
iter[len]
TypeError: 'builtin_function_or_method' object is not iterable
1 in the loop body are denoted by indentation, as with all Python control structures, and are executed once for each item in >>> iter[42] # Integer
Traceback [most recent call last]:
File "", line 1, in
iter[42]
TypeError: 'int' object is not iterable
>>> iter[3.1] # Float
Traceback [most recent call last]:
File "", line 1, in
iter[3.1]
TypeError: 'float' object is not iterable
>>> iter[len] # Built-in function
Traceback [most recent call last]:
File "", line 1, in
iter[len]
TypeError: 'builtin_function_or_method' object is not iterable
0. The loop variable >>> iter[42] # Integer
Traceback [most recent call last]:
File "", line 1, in
iter[42]
TypeError: 'int' object is not iterable
>>> iter[3.1] # Float
Traceback [most recent call last]:
File "", line 1, in
iter[3.1]
TypeError: 'float' object is not iterable
>>> iter[len] # Built-in function
Traceback [most recent call last]:
File "", line 1, in
iter[len]
TypeError: 'builtin_function_or_method' object is not iterable
3 takes on the value of the next element in >>> iter[42] # Integer
Traceback [most recent call last]:
File "", line 1, in
iter[42]
TypeError: 'int' object is not iterable
>>> iter[3.1] # Float
Traceback [most recent call last]:
File "", line 1, in
iter[3.1]
TypeError: 'float' object is not iterable
>>> iter[len] # Built-in function
Traceback [most recent call last]:
File "", line 1, in
iter[len]
TypeError: 'builtin_function_or_method' object is not iterable
0 each time through the loop.Here is a representative example:
>>>
>>> a = ['foo', 'bar', 'baz']
>>> for i in a:
... print[i]
...
foo
bar
baz
In this example,
>>> iter[42] # Integer
Traceback [most recent call last]:
File "", line 1, in
iter[42]
TypeError: 'int' object is not iterable
>>> iter[3.1] # Float
Traceback [most recent call last]:
File "", line 1, in
iter[3.1]
TypeError: 'float' object is not iterable
>>> iter[len] # Built-in function
Traceback [most recent call last]:
File "", line 1, in
iter[len]
TypeError: 'builtin_function_or_method' object is not iterable
0 is the list >>> iter[42] # Integer
Traceback [most recent call last]:
File "", line 1, in
iter[42]
TypeError: 'int' object is not iterable
>>> iter[3.1] # Float
Traceback [most recent call last]:
File "", line 1, in
iter[3.1]
TypeError: 'float' object is not iterable
>>> iter[len] # Built-in function
Traceback [most recent call last]:
File "", line 1, in
iter[len]
TypeError: 'builtin_function_or_method' object is not iterable
6, and >>> iter[42] # Integer
Traceback [most recent call last]:
File "", line 1, in
iter[42]
TypeError: 'int' object is not iterable
>>> iter[3.1] # Float
Traceback [most recent call last]:
File "", line 1, in
iter[3.1]
TypeError: 'float' object is not iterable
>>> iter[len] # Built-in function
Traceback [most recent call last]:
File "", line 1, in
iter[len]
TypeError: 'builtin_function_or_method' object is not iterable
3 is the variable for in :
7. Each time through the loop, for in :
7 takes on a successive item in >>> iter[42] # Integer
Traceback [most recent call last]:
File "", line 1, in
iter[42]
TypeError: 'int' object is not iterable
>>> iter[3.1] # Float
Traceback [most recent call last]:
File "", line 1, in
iter[3.1]
TypeError: 'float' object is not iterable
>>> iter[len] # Built-in function
Traceback [most recent call last]:
File "", line 1, in
iter[len]
TypeError: 'builtin_function_or_method' object is not iterable
6, so >>> a = ['foo', 'bar', 'baz']
>>> itr = iter[a]
>>> itr
>>> next[itr]
'foo'
>>> next[itr]
'bar'
>>> next[itr]
'baz'
1 displays the values >>> a = ['foo', 'bar', 'baz']
>>> itr = iter[a]
>>> itr
>>> next[itr]
'foo'
>>> next[itr]
'bar'
>>> next[itr]
'baz'
2, >>> a = ['foo', 'bar', 'baz']
>>> itr = iter[a]
>>> itr
>>> next[itr]
'foo'
>>> next[itr]
'bar'
>>> next[itr]
'baz'
3, and >>> a = ['foo', 'bar', 'baz']
>>> itr = iter[a]
>>> itr
>>> next[itr]
'foo'
>>> next[itr]
'bar'
>>> next[itr]
'baz'
4, respectively. A for in :
0 loop like this is the Pythonic way to process the items in an iterable.But what exactly is an iterable? Before examining
for in :
0 loops further, it will be beneficial to delve more deeply into what iterables are in Python.Remove adsIterables
In Python, iterable means an object can be used in iteration. The term is used as:
- An adjective: An object may be described as iterable.
- A noun: An object may be characterized as an iterable.
If an object is iterable, it can be passed to the built-in Python function
>>> a = ['foo', 'bar', 'baz']
>>> itr = iter[a]
>>> itr
>>> next[itr]
'foo'
>>> next[itr]
'bar'
>>> next[itr]
'baz'
7, which returns something called an iterator. Yes, the terminology gets a bit repetitive. Hang in there. It all works out in the end.Each of the objects in the following example is an iterable and returns some type of iterator when passed to
>>> a = ['foo', 'bar', 'baz']
>>> itr = iter[a]
>>> itr
>>> next[itr]
'foo'
>>> next[itr]
'bar'
>>> next[itr]
'baz'
7:>>>
>>> iter['foobar'] # String
>>> iter[['foo', 'bar', 'baz']] # List
>>> iter[['foo', 'bar', 'baz']] # Tuple
>>> iter[{'foo', 'bar', 'baz'}] # Set
>>> iter[{'foo': 1, 'bar': 2, 'baz': 3}] # Dict
These object types, on the other hand, aren’t iterable:
>>>
>>> iter[42] # Integer
Traceback [most recent call last]:
File "", line 1, in
iter[42]
TypeError: 'int' object is not iterable
>>> iter[3.1] # Float
Traceback [most recent call last]:
File "", line 1, in
iter[3.1]
TypeError: 'float' object is not iterable
>>> iter[len] # Built-in function
Traceback [most recent call last]:
File "", line 1, in
iter[len]
TypeError: 'builtin_function_or_method' object is not iterable
All the data types you have encountered so far that are collection or container types are iterable. These include the string, list, tuple, dict, set, and frozenset types.
But these are by no means the only types that you can iterate over. Many objects that are built into Python or defined in modules are designed to be iterable. For example, open files in Python are iterable. As you will see soon in the tutorial on file I/O, iterating over an open file object reads data from the file.
In fact, almost any object in Python can be made iterable. Even user-defined objects can be designed in such a way that they can be iterated over. [You will find out how that is done in the upcoming article on object-oriented programming.]
Iterators
Okay, now you know what it means for an object to be iterable, and you know how to use
>>> a = ['foo', 'bar', 'baz']
>>> itr = iter[a]
>>> itr
>>> next[itr]
'foo'
>>> next[itr]
'bar'
>>> next[itr]
'baz'
7 to obtain an iterator from it. Once you’ve got an iterator, what can you do with it?An iterator is essentially a value producer that yields successive values from its associated iterable object. The built-in function
>>> next[itr]
Traceback [most recent call last]:
File "", line 1, in
next[itr]
StopIteration
0 is used to obtain the next value from in iterator.Here is an example using the same list as above:
>>>
>>> a = ['foo', 'bar', 'baz']
>>> itr = iter[a]
>>> itr
>>> next[itr]
'foo'
>>> next[itr]
'bar'
>>> next[itr]
'baz'
In this example,
>>> iter[42] # Integer
Traceback [most recent call last]:
File "", line 1, in
iter[42]
TypeError: 'int' object is not iterable
>>> iter[3.1] # Float
Traceback [most recent call last]:
File "", line 1, in
iter[3.1]
TypeError: 'float' object is not iterable
>>> iter[len] # Built-in function
Traceback [most recent call last]:
File "", line 1, in
iter[len]
TypeError: 'builtin_function_or_method' object is not iterable
6 is an iterable list and >>> next[itr]
Traceback [most recent call last]:
File "", line 1, in
next[itr]
StopIteration
2 is the associated iterator, obtained with >>> a = ['foo', 'bar', 'baz']
>>> itr = iter[a]
>>> itr
>>> next[itr]
'foo'
>>> next[itr]
'bar'
>>> next[itr]
'baz'
7. Each >>> next[itr]
Traceback [most recent call last]:
File "", line 1, in
next[itr]
StopIteration
4 call obtains the next value from >>> next[itr]
Traceback [most recent call last]:
File "", line 1, in
next[itr]
StopIteration
2.Notice how an iterator retains its state internally. It knows which values have been obtained already, so when you call
>>> next[itr]
Traceback [most recent call last]:
File "", line 1, in
next[itr]
StopIteration
0, it knows what value to return next.What happens when the iterator runs out of values? Let’s make one more
>>> next[itr]
Traceback [most recent call last]:
File "", line 1, in
next[itr]
StopIteration
0 call on the iterator above:>>>
>>> next[itr]
Traceback [most recent call last]:
File "", line 1, in
next[itr]
StopIteration
If all the values from an iterator have been returned already, a subsequent
>>> next[itr]
Traceback [most recent call last]:
File "", line 1, in
next[itr]
StopIteration
0 call raises a >>> next[itr]
Traceback [most recent call last]:
File "", line 1, in
next[itr]
StopIteration
9 exception. Any further attempts to obtain values from the iterator will fail.You can only obtain values from an iterator in one direction. You can’t go backward. There is no
>>> a
['foo', 'bar', 'baz']
>>> itr1 = iter[a]
>>> itr2 = iter[a]
>>> next[itr1]
'foo'
>>> next[itr1]
'bar'
>>> next[itr1]
'baz'
>>> next[itr2]
'foo'
0 function. But you can define two independent iterators on the same iterable object:>>>
>>> a
['foo', 'bar', 'baz']
>>> itr1 = iter[a]
>>> itr2 = iter[a]
>>> next[itr1]
'foo'
>>> next[itr1]
'bar'
>>> next[itr1]
'baz'
>>> next[itr2]
'foo'
Even when iterator
>>> a
['foo', 'bar', 'baz']
>>> itr1 = iter[a]
>>> itr2 = iter[a]
>>> next[itr1]
'foo'
>>> next[itr1]
'bar'
>>> next[itr1]
'baz'
>>> next[itr2]
'foo'
1 is already at the end of the list, >>> a
['foo', 'bar', 'baz']
>>> itr1 = iter[a]
>>> itr2 = iter[a]
>>> next[itr1]
'foo'
>>> next[itr1]
'bar'
>>> next[itr1]
'baz'
>>> next[itr2]
'foo'
2 is still at the beginning. Each iterator maintains its own internal state, independent of the other.If you want to grab all the values from an iterator at once, you can use the built-in
>>> a
['foo', 'bar', 'baz']
>>> itr1 = iter[a]
>>> itr2 = iter[a]
>>> next[itr1]
'foo'
>>> next[itr1]
'bar'
>>> next[itr1]
'baz'
>>> next[itr2]
'foo'
3 function. Among other possible uses, >>> a
['foo', 'bar', 'baz']
>>> itr1 = iter[a]
>>> itr2 = iter[a]
>>> next[itr1]
'foo'
>>> next[itr1]
'bar'
>>> next[itr1]
'baz'
>>> next[itr2]
'foo'
3 takes an iterator as its argument, and returns a list consisting of all the values that the iterator yielded:>>>
for [i = 1; i >> a
['foo', 'bar', 'baz']
>>> itr1 = iter[a]
>>> itr2 = iter[a]
>>> next[itr1]
'foo'
>>> next[itr1]
'bar'
>>> next[itr1]
'baz'
>>> next[itr2]
'foo'
5 and >>> a
['foo', 'bar', 'baz']
>>> itr1 = iter[a]
>>> itr2 = iter[a]
>>> next[itr1]
'foo'
>>> next[itr1]
'bar'
>>> next[itr1]
'baz'
>>> next[itr2]
'foo'
6 functions return a tuple and a set, respectively, from all the values an iterator yields:>>>
for [i = 1; i >> next[itr]
Traceback [most recent call last]:
File "", line 1, in
next[itr]
StopIteration
0. Items are not created until they are requested.When you use
>>> a
['foo', 'bar', 'baz']
>>> itr1 = iter[a]
>>> itr2 = iter[a]
>>> next[itr1]
'foo'
>>> next[itr1]
'bar'
>>> next[itr1]
'baz'
>>> next[itr2]
'foo'
3, >>> a
['foo', 'bar', 'baz']
>>> itr1 = iter[a]
>>> itr2 = iter[a]
>>> next[itr1]
'foo'
>>> next[itr1]
'bar'
>>> next[itr1]
'baz'
>>> next[itr2]
'foo'
5, or the like, you are forcing the iterator to generate all its values at once, so they can all be returned. If the total number of objects the iterator returns is very large, that may take a long time.In fact, it is possible to create an iterator in Python that returns an endless series of objects using generator functions and
for [i = 1; i >> a = ['foo', 'bar', 'baz']
>>> itr = iter[a]
>>> itr
>>> next[itr]
'foo'
>>> next[itr]
'bar'
>>> next[itr]
'baz'
7The built-in function used to obtain an iterator from an iterableNow, consider again the simple
for in :
0 loop presented at the start of this tutorial:>>>
>>> a = ['foo', 'bar', 'baz']
>>> for i in a:
... print[i]
...
foo
bar
baz
This loop can be described entirely in terms of the concepts you have just learned about. To carry out the iteration this
for in :
0 loop describes, Python does the following:- Calls
7 to obtain an iterator for>>> a = ['foo', 'bar', 'baz'] >>> itr = iter[a] >>> itr >>> next[itr] 'foo' >>> next[itr] 'bar' >>> next[itr] 'baz'
6>>> iter[42] # Integer Traceback [most recent call last]: File "", line 1, in iter[42] TypeError: 'int' object is not iterable >>> iter[3.1] # Float Traceback [most recent call last]: File "", line 1, in iter[3.1] TypeError: 'float' object is not iterable >>> iter[len] # Built-in function Traceback [most recent call last]: File "", line 1, in iter[len] TypeError: 'builtin_function_or_method' object is not iterable
- Calls
0 repeatedly to obtain each item from the iterator in turn>>> next[itr] Traceback [most recent call last]: File "", line 1, in next[itr] StopIteration
- Terminates the loop when
0 raises the>>> next[itr] Traceback [most recent call last]: File "", line 1, in next[itr] StopIteration
9 exception>>> next[itr] Traceback [most recent call last]: File "", line 1, in next[itr] StopIteration
The loop body is executed once for each item
>>> next[itr]
Traceback [most recent call last]:
File "", line 1, in
next[itr]
StopIteration
0 returns, with loop variable for in :
7 set to the given item for each iteration.This sequence of events is summarized in the following diagram:
Perhaps this seems like a lot of unnecessary monkey business, but the benefit is substantial. Python treats looping over all iterables in exactly this way, and in Python, iterables and iterators abound:
Many built-in and library objects are iterable.
There is a Standard Library module called
7, so you know dictionaries must be iterable. What happens when you loop through a dictionary? Let’s see:for [i = 1; i >> a = ['foo', 'bar', 'baz'] >>> itr = iter[a] >>> itr >>> next[itr] 'foo' >>> next[itr] 'bar' >>> next[itr] 'baz'
>>>
for [i = 1; i >>
for [i = 1; i >
for [i = 1; i >>
for [i = 1; i >
for [i = 1; i >>
3 orfor [i = 1; i a ['foo', 'bar', 'baz'] >>> itr1 = iter[a] >>> itr2 = iter[a] >>> next[itr1] 'foo' >>> next[itr1] 'bar' >>> next[itr1] 'baz' >>> next[itr2] 'foo'
5. In a REPL session, that can be a convenient way to quickly display what the values are:>>> a ['foo', 'bar', 'baz'] >>> itr1 = iter[a] >>> itr2 = iter[a] >>> next[itr1] 'foo' >>> next[itr1] 'bar' >>> next[itr1] 'baz' >>> next[itr2] 'foo'
>>>
2for i in
However, when
3 orfor [i = 1; i >> a ['foo', 'bar', 'baz'] >>> itr1 = iter[a] >>> itr2 = iter[a] >>> next[itr1] 'foo' >>> next[itr1] 'bar' >>> next[itr1] 'baz' >>> next[itr2] 'foo'
5 in this way. Like iterators,>>> a ['foo', 'bar', 'baz'] >>> itr1 = iter[a] >>> itr2 = iter[a] >>> next[itr1] 'foo' >>> next[itr1] 'bar' >>> next[itr1] 'baz' >>> next[itr2] 'foo'
3 orfor [i = 1; i >> a ['foo', 'bar', 'baz'] >>> itr1 = iter[a] >>> itr2 = iter[a] >>> next[itr1] 'foo' >>> next[itr1] 'bar' >>> next[itr1] 'baz' >>> next[itr2] 'foo'
5 on a>>> a ['foo', 'bar', 'baz'] >>> itr1 = iter[a] >>> itr2 = iter[a] >>> next[itr1] 'foo' >>> next[itr1] 'bar' >>> next[itr1] 'baz' >>> next[itr2] 'foo'
for [i = 1; i
4for i in
All the parameters specified to
for [i = 1; i