Python Basics #15 — for Loop
In today’s lesson we’ll cover the for loop.
Python’s for loop is used to iterate over a collection of data sequentially. It’s similar to while but in most cases more convenient — and the more commonly used of the two.
Any sequence-type object can be used in a for loop. To check whether an object is iterable, use the iter function. Sequence-type objects usable in a for loop include strings, lists, dictionaries, tuples, sets, and range objects.
Sequence-type objects usable in a
forloop
- String
- List
- Dictionary
- Tuple
- Set
- Range
Objects you can’t use in a for loop — non-sequence types — include int, float, bool, None, and function objects.
Objects NOT usable in a
forloop
- Integer
- Float
- Boolean
- None
- Function
As mentioned, the iter function tells you whether an object can be used in a for loop. If passing the object to iter returns an iterator object, it’s iterable; if it raises a TypeError, it isn’t.
Verify with iterable objects:
# objects usable in a for loop
my_string = 'abc'
my_list = [1, 2, 3]
my_dict = {'a': 1, 'b': 2}
my_set = {'a', 'b', 'c'}
my_range = range(10)
print('String: {}'.format(iter(my_string)))
print('List: {}'.format(iter(my_list)))
print('Dictionary: {}'.format(iter(my_dict)))
print('Set: {}'.format(iter(my_set)))
print('Range: {}'.format(iter(my_range)))String: <str_iterator object at 0x000001F326934BB0>
List: <list_iterator object at 0x000001F3247614F0>
Dictionary: <dict_keyiterator object at 0x000001F3274E0860>
Set: <set_iterator object at 0x000001F3274EFC00>
Range: <range_iterator object at 0x000001F326908D10>All iterable objects passed to iter return an iterator object.
Now let’s verify with non-iterable objects:
# objects NOT usable in a for loop
my_integer = 1
my_float = 1.234
my_bool = True
my_none = None
def my_func():
pass
print('Integer: {}'.format(iter(my_integer)))
TypeError: 'int' object is not iterableNon-iterable objects passed to iter raise a TypeError. Try float, bool, None, and the function object yourself.
Run a for loop on a string (an iterable):
my_string = 'abc'
for letter in my_string:
print(letter)
a
b
cAs the loop runs, the variable letter is assigned each character one at a time.
How does a for loop work internally? You need to understand iter and next first.
Pass a string to iter to create a str_iterator, then call __next__ to get characters one by one:
iter_obj = iter('abc')
print(iter_obj)
print(iter_obj.__next__())
print(iter_obj.__next__())
print(iter_obj.__next__())
print(iter_obj.__next__())
<str_iterator object at 0x000001F324761250>
a
b
c
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
in
5 print(iter_obj.__next__())
6 print(iter_obj.__next__())
----> 7 print(iter_obj.__next__())a, b, c print sequentially, then a StopIteration is raised when there’s nothing left. iter takes a sequence object and returns an iterator object. The iterator has a __next__ method; calling it returns the next element. When there’s nothing left to return, it raises StopIteration.
Inside a for loop you can use two helper keywords: continue and break. continue skips the current iteration; break exits the loop. Let’s use both:
my_list = ['one', 'two', 'three', 'skip', 'four', 'five']
for num in my_list:
if num == 'skip':
continue # skip when the value is 'skip'
print(num)
if num == 'four':
break # exit the loop when the value is 'four'
one
two
three
fourWhen using for loops you’ll sometimes want to unpack items. For example, when iterating over a list of lists, the inner list is bound to a single variable:
list_1 = [[1, 2], [3, 4], [5, 6]]
for i in list_1:
print(i)
[1, 2]
[3, 4]
[5, 6]But if you declare two variables in the for, each inner-list item gets bound to its own variable. That’s unpacking:
list_1 = [[1, 2], [3, 4], [5, 6]]
for i, j in list_1:
print(i, j)
1 2
3 4
5 6You could also use a nested for loop to access each item, but with a small inner length, unpacking is more convenient.
Unpacking works for more than two items too:
list_2 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for i, j, k in list_2:
print(i, j, k)
1 2 3
4 5 6
7 8 9If the number of unpack targets and items don’t match, you get an error:
list_2 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for i, j in list_2:
print(i, j)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-20-19b25bdbc030> in <module>
2 list_2 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
3
----> 4 for i, j in list_2:
5 print(i, j)
ValueError: too many values to unpack (expected 2)Now let’s see how to use a dictionary in a for loop. Define a small dict and run a for loop:
my_dict = {
'a': 1,
'b': 2,
'c': 3
}
for i in my_dict:
print(i)
a
b
cIterating a dictionary yields keys, not values. To get the value, look it up using the returned key:
my_dict = {
'a': 1,
'b': 2,
'c': 3
}
for key in my_dict:
print('{}: {}'.format(key, my_dict[key]))
a: 1
b: 2
c: 3Or use the items method:
my_dict = {
'a': 1,
'b': 2,
'c': 3
}
for i in my_dict.items():
print(i)
('a', 1)
('b', 2)
('c', 3)items returns each (key, value) pair as a tuple. With unpacking:
my_dict = {
'a': 1,
'b': 2,
'c': 3
}
for k, v in my_dict.items():
print('{}: {}'.format(k, v))
a: 1
b: 2
c: 3Sets are also iterable. Sets are unordered, so the iteration order in for doesn’t match insertion order:
my_set = {'a', 'b', 'c'}
for i in my_set:
print(i)
c
b
aFinally, the range object.
The range function is commonly used when you want to iterate a specific number of times. To print 1 through 10:
for i in range(1, 11):
print(i)
1
2
3
4
5
6
7
8
9
10A common coding-test problem is to use a loop to print a multiplication table. Using for and range:
for i in range(1, 10):
for j in range(2, 10):
result = '{} x {} = {}'.format(j, i, j * i)
print('{:10s}'.format(result), end='\\t')
print()
2 x 1 = 2 3 x 1 = 3 4 x 1 = 4 5 x 1 = 5 6 x 1 = 6 7 x 1 = 7 8 x 1 = 8 9 x 1 = 9
2 x 2 = 4 3 x 2 = 6 4 x 2 = 8 5 x 2 = 10 6 x 2 = 12 7 x 2 = 14 8 x 2 = 16 9 x 2 = 18
2 x 3 = 6 3 x 3 = 9 4 x 3 = 12 5 x 3 = 15 6 x 3 = 18 7 x 3 = 21 8 x 3 = 24 9 x 3 = 27
2 x 4 = 8 3 x 4 = 12 4 x 4 = 16 5 x 4 = 20 6 x 4 = 24 7 x 4 = 28 8 x 4 = 32 9 x 4 = 36
2 x 5 = 10 3 x 5 = 15 4 x 5 = 20 5 x 5 = 25 6 x 5 = 30 7 x 5 = 35 8 x 5 = 40 9 x 5 = 45
2 x 6 = 12 3 x 6 = 18 4 x 6 = 24 5 x 6 = 30 6 x 6 = 36 7 x 6 = 42 8 x 6 = 48 9 x 6 = 54
2 x 7 = 14 3 x 7 = 21 4 x 7 = 28 5 x 7 = 35 6 x 7 = 42 7 x 7 = 49 8 x 7 = 56 9 x 7 = 63
2 x 8 = 16 3 x 8 = 24 4 x 8 = 32 5 x 8 = 40 6 x 8 = 48 7 x 8 = 56 8 x 8 = 64 9 x 8 = 72
2 x 9 = 18 3 x 9 = 27 4 x 9 = 36 5 x 9 = 45 6 x 9 = 54 7 x 9 = 63 8 x 9 = 72 9 x 9 = 81A multiplication table built easily.
That wraps up today’s lesson. In the next lesson we’ll cover functions.