11.1. For About
Iterating works for builtin sequences
Works with:
str
,bytes
,list
,tuple
,set
,dict
11.1.1. Problem
>>> data = ['a', 'b', 'c']
>>> i = 0
>>>
>>> while i < len(data):
... x = data[i]
... print(x)
... i += 1
a
b
c
11.1.2. Solution
>>> data = ['a', 'b', 'c']
>>>
>>> for x in data:
... print(x)
a
b
c
11.1.3. Iterating Str
>>> DATA = 'abc'
>>>
>>> for x in DATA:
... print(x)
a
b
c
11.1.4. Iterating Tuple
>>> DATA = ('a', 'b', 'c')
>>>
>>> for x in DATA:
... print(x)
a
b
c
11.1.5. Iterating List
>>> DATA = ['a', 'b', 'c']
>>>
>>> for x in DATA:
... print(x)
a
b
c
11.1.6. Iterating Set
Set order depends on element
hash
Each time the result of the function will be different
Use
sorted(DATA)
to get deterministic order
Set order depends on element hash
, therefore each time the result
of the function will be different:
>>> DATA = {'a', 'b', 'c'}
>>>
>>> for x in DATA:
... print(x)
c
a
b
Use sorted(DATA)
to get deterministic order:
>>> DATA = {'a', 'b', 'c'}
>>>
>>> for x in sorted(DATA):
... print(x)
a
b
c
11.1.7. Iterating Dict
By default iterating is over the keys
More information in For Dict
>>> DATA = {'a':1, 'b':2, 'c':3}
>>>
>>> for x in DATA:
... print(x)
a
b
c
11.1.8. Naming Current Element
The longer the loop scope, the longer the variable name should be
Avoid single-letter variables if scope is longer than one line
Prefer locally meaningful name over generic names
Good names:
letter
,digit
,number
,user
,color
,sentence
Ok names (depends on the scope):
x
,value
,item
Bad names:
obj
,element
,e
,v
Very bad names:
i
(by convention it is a loop counter)
Good names:
>>> data = [1, 2, 3]
>>>
>>> for number in data:
... print(number)
1
2
3
>>> data = ['a', 'b', 'c']
>>>
>>> for letter in data:
... print(letter)
a
b
c
Ok names:
>>> data = ['a', 'b', 'c']
>>>
>>> for item in data:
... print(item)
a
b
c
>>> data = ['a', 'b', 'c']
>>>
>>> for value in data:
... print(value)
a
b
c
Bad names:
>>> data = ['a', 'b', 'c']
>>>
>>> for element in data:
... print(element)
a
b
c
Very bad names: i
(by convention it is a loop counter):
>>> data = ['a', 'b', 'c']
>>>
>>> for i in data:
... print(i)
a
b
c
11.1.9. Note to the Programmers of Other Languages
In programming we have multiple types of loops:
for
,foreach
,while
,do while
,until
,loop
In Python we have two types of loops:
for
,while
Python
for
behaves likeforeach
in other languages
There are several types of loops in general:
for
foreach
while
do while
until
But in Python we have only two:
while
for
This does not takes into consideration comprehensions and generator expressions, which will be covered in next chapters.
Note, that Python for
is not the same as for
in other languages,
such as C, C++, C#, JAVA, Java Script. Python for
loop is more like
foreach
. Check the following example in JAVA:
char[] DATA = {'a', 'b', 'c'};
forEach (var letter : DATA) {
System.out.println(letter);
}
$data = array('a', 'b', 'c');
foreach ($data as $letter) {
echo $letter;
}
DATA = ['a', 'b', 'c']
for (let letter of DATA) {
console.log(letter)
}
And this relates to Python regular for
loop:
>>> DATA = ['a', 'b', 'c']
>>>
>>> for letter in DATA:
... print(letter)
a
b
c
Regular for
loop in other languages looks like that (example in C++):
char DATA[] = {'a', 'b', 'c'}
for (int i = 0; i < std::size(DATA); i++) {
letter = data[i];
printf(letter);
}
Python equivalent will be:
>>> DATA = ['a', 'b', 'c']
>>> i = 0
>>>
>>> while i < len(DATA):
... letter = DATA[i]
... print(letter)
... i += 1
a
b
c
Yes, that's true, it is a while
loop. This is due to the fact, that
for
loop from other languages is more like a while
loop in Python.
Nevertheless, the very common bad practice is to do range(len())
:
>>> data = ['a', 'b', 'c']
>>>
>>> for i in range(len(data)):
... letter = data[i]
... print(letter)
a
b
c
Note, how similar are those concepts. This is trying to take syntax from other
languages and apply it to Python. range(len())
is considered a bad practice
and it will not work with generators. But it gives similar look-and-feel.
Please remember:
Python
for
is more likeforeach
in other languages.Python
while
is more likefor
in other languages.
foreach data as x:
print(x)
11.1.10. Recap
Iterating works for builtin sequences
Works with:
str
,bytes
,list
,tuple
,set
,dict
11.1.11. Assignments
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: For About Count
# - Difficulty: easy
# - Lines: 7
# - Minutes: 5
# %% English
# 1. Count occurrences of each color
# 2. Do not use `list.count()`
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zlicz wystąpienia każdego z kolorów
# 2. Nie używaj `list.count()`
# 3. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> assert red is not Ellipsis, \
'Assign your result to variable `red`'
>>> assert green is not Ellipsis, \
'Assign your result to variable `green`'
>>> assert blue is not Ellipsis, \
'Assign your result to variable `blue`'
>>> assert type(red) is int, \
'Variable `red` has invalid type, should be list'
>>> assert type(green) is int, \
'Variable `green` has invalid type, should be list'
>>> assert type(blue) is int, \
'Variable `blue` has invalid type, should be list'
>>> red
3
>>> green
2
>>> blue
2
"""
DATA = ['red', 'green', 'blue', 'red', 'green', 'red', 'blue']
red = 0
green = 0
blue = 0
# If variable COLOR is:
# - 'red' then increment variable `red` by 1
# - 'green' then increment variable `green` by 1
# - 'blue' then increment variable `blue` by 1
...
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: For About Counter
# - Difficulty: easy
# - Lines: 5
# - Minutes: 5
# %% English
# 1. Iterate over `DATA` and count occurrences of each color
# 2. Define `result: dict[str, int]`:
# - key - color name
# - value - number of occurrences
# 3. Do not use `list.count()`
# 4. Run doctests - all must succeed
# %% Polish
# 1. Iteruj po `DATA` i policz wystąpienia każde go koloru
# 2. Zdefiniuj `result: dict[int, int]`:
# - klucz - nazwa koloru
# - wartość - liczba wystąpień
# 3. Nie używaj `list.count()`
# 4. Uruchom doctesty - wszystkie muszą się powieść
# %% Hints
# - Check if `color` is already in `result`
# - If does not exist, then add it to `result` with value 1
# - If exists, then increment the value by 1
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> assert result is not Ellipsis, \
'Assign your result to variable `result`'
>>> assert type(result) is dict, \
'Variable `result` has invalid type, should be dict'
>>> assert all(type(x) is int for x in result.values()), \
'All values must be `int`'
>>> assert 'red' in result.keys()
>>> assert 'green' in result.keys()
>>> assert 'blue' in result.keys()
>>> result
{'red': 3, 'green': 2, 'blue': 2}
"""
DATA = ['red', 'green', 'blue', 'red', 'green', 'red', 'blue']
# Iterate over `DATA` and count occurrences of each color
# Define `result: dict[str, int]`:
# - key - color name
# - value - number of occurrences
# type: dict[int,int]
result = ...
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: For About Segmentation
# - Difficulty: easy
# - Lines: 10
# - Minutes: 8
# %% English
# 1. Count number of occurrences for digit in segments:
# - 'small' - digitst in range [0-3)
# - 'medium' - digitst in range [3-7)
# - 'large' - digitst in range [7-10)
# 2. Notation `[0-3)` - means, digits between 0 and 3, without 3 (left-side closed)
# 3. Run doctests - all must succeed
# %% Polish
# 1. Policz liczbę wystąpień cyfr w przedziałach:
# - 'small' - cyfry z przedziału <0-3)
# - 'medium' - cyfry z przedziału <3-7)
# - 'large' - cyfry z przedziału <7-10)
# 2. Zapis `<0-3)` - znaczy, cyfry od 0 do 3, bez 3 (lewostronnie domknięty)
# 3. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> assert result is not Ellipsis, \
'Assign your result to variable `result`'
>>> assert type(result) is dict, \
'Variable `result` has invalid type, should be dict'
>>> assert all(type(x) is str for x in result.keys())
>>> assert all(type(x) is int for x in result.values())
>>> result
{'small': 16, 'medium': 19, 'large': 15}
"""
DATA = [
1, 4, 6, 7, 4, 4, 4, 5, 1, 7, 0,
0, 6, 5, 0, 0, 9, 7, 0, 4, 4, 8,
2, 4, 0, 0, 1, 9, 1, 7, 8, 8, 9,
1, 3, 5, 6, 8, 2, 8, 1, 3, 9, 5,
4, 8, 1, 9, 6, 3,
]
# Number of digit occurrences in segments
# type: dict[str,int]
result = {'small': 0, 'medium': 0, 'large': 0}
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: For About Newlines
# - Difficulty: easy
# - Lines: 2
# - Minutes: 5
# %% English
# 1. Define `result: str`
# 2. Use `for` to iterate over `DATA`
# 3. Join lines of text with newline (`\n`) character
# 4. Do not use `str.join()`
# 5. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj `result: str`
# 2. Użyj `for` do iterowania po `DATA`
# 3. Połącz linie tekstu znakiem końca linii (`\n`)
# 4. Nie używaj `str.join()`
# 5. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from pprint import pprint
>>> assert result is not Ellipsis, \
'Assign your result to variable `result`'
>>> assert type(result) is str, \
'Variable `result` has invalid type, should be str'
>>> result.count('\\n')
3
>>> pprint(result)
('We choose to go to the Moon.\\n'
'We choose to go to the Moon in this decade and do the other things.\\n'
'Not because they are easy, but because they are hard.\\n')
"""
DATA = [
'We choose to go to the Moon.',
'We choose to go to the Moon in this decade and do the other things.',
'Not because they are easy, but because they are hard.',
]
# DATA joined with newline - \n
# type: str
result = ...
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: For About Remove PL Chars
# - Difficulty: easy
# - Lines: 2
# - Minutes: 5
# %% English
# 1. Define `result: str`
# 2. Use `for` to iterate over `DATA`
# 3. If letter is in `PL` then use conversion value as letter
# 4. Add letter to `result`
# 5. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj `result: str`
# 2. Użyj `for` do iteracji po `DATA`
# 3. Jeżeli litera jest w `PL` to użyj przekonwertowanej wartości jako litera
# 4. Dodaj literę do `result`
# 5. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> assert result is not Ellipsis, \
'Assign your result to variable `result`'
>>> assert type(result) is str, \
'Variable `result` has invalid type, should be str'
>>> result
'zazolc gesla jazn'
"""
PL = {
'ą': 'a',
'ć': 'c',
'ę': 'e',
'ł': 'l',
'ń': 'n',
'ó': 'o',
'ś': 's',
'ż': 'z',
'ź': 'z',
}
DATA = 'zażółć gęślą jaźń'
# DATA with substituted PL diacritic chars to ASCII letters
# type: str
result = ...
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: For About Months
# - Difficulty: easy
# - Lines: 4
# - Minutes: 5
# %% English
# 1. Convert `MONTH` into `result: dict[int,str]`:
# - Keys: month number
# - Values: month name
# 2. Run doctests - all must succeed
# %% Polish
# 1. Przekonwertuj `MONTH` w `result: dict[int,str]`:
# - klucz: numer miesiąca
# - wartość: nazwa miesiąca
# 2. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from pprint import pprint
>>> assert result is not Ellipsis, \
'Assign your result to variable `result`'
>>> assert type(result) is dict, \
'Variable `result` has invalid type, should be dict'
>>> assert all(type(x) is int for x in result.keys())
>>> assert all(type(x) is str for x in result.values())
>>> assert all(x in result.keys() for x in range(1, 13))
>>> assert all(x in result.values() for x in MONTHS)
>>> 13 not in result
True
>>> 0 not in result
True
>>> pprint(result)
{1: 'January',
2: 'February',
3: 'March',
4: 'April',
5: 'May',
6: 'June',
7: 'July',
8: 'August',
9: 'September',
10: 'October',
11: 'November',
12: 'December'}
"""
MONTHS = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
# Dict with month number and name. Start with 1
# type: dict[int,str]
result = ...
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: For About Endswith
# - Difficulty: easy
# - Lines: 5
# - Minutes: 5
# %% English
# 1. Define `result: list[str]`
# 2. Collect in `result` all email addresses from `DATA` -> `crew`
# with domain names mentioned in `DOMAINS`
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj `result: list[str]`
# 2. Zbierz w `result` wszystkie adresy email z `DATA` -> `crew`
# z nazwami domenowymi wymienionymi w `DOMAINS`
# 3. Uruchom doctesty - wszystkie muszą się powieść
# %% Why
# - Check if you can filter data
# - Check if you know string methods
# - Check if you know how to iterate over list[dict]
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from pprint import pprint
>>> assert result is not Ellipsis, \
'Assign result to variable: `result`'
>>> assert type(result) is list, \
'Result must be a list'
>>> assert len(result) > 0, \
'Result cannot be empty'
>>> assert all(type(element) is str for element in result), \
'All elements in result must be a str'
>>> result = sorted(result)
>>> pprint(result)
['avogel@esa.int',
'bjohanssen@nasa.gov',
'cbeck@nasa.gov',
'mlewis@nasa.gov',
'mwatney@nasa.gov',
'rmartinez@nasa.gov']
"""
DATA = [
{'name': 'Mark Watney', 'email': 'mwatney@nasa.gov'},
{'name': 'Melissa Lewis', 'email': 'mlewis@nasa.gov'},
{'name': 'Rick Martinez', 'email': 'rmartinez@nasa.gov'},
{'name': 'Pan Twardowski', 'email': 'ptwardowski@polsa.gov.pl'},
{'name': 'Alex Vogel', 'email': 'avogel@esa.int'},
{'name': 'Chris Beck', 'email': 'cbeck@nasa.gov'},
{'name': 'Ivan Ivanovich', 'email': 'iivanovich@roscosmos.ru'},
{'name': 'Beth Johanssen', 'email': 'bjohanssen@nasa.gov'},
]
DOMAINS = ('esa.int', 'nasa.gov')
# Email addresses with top-level domain in DOMAINS
# type: list[str]
result = ...