12.1. For About
Iterating works for builtin sequences
Works with:
str
,bytes
,list
,tuple
,set
,dict
Naming Current Element:
letter
,digit
,number
,user
,color
,sentence
Iterating Str:
>>> DATA = 'abc'
>>>
>>> for x in DATA:
... print(x)
a
b
c
Iterating Tuple:
>>> DATA = ('a', 'b', 'c')
>>>
>>> for x in DATA:
... print(x)
a
b
c
Iterating List:
>>> DATA = ['a', 'b', 'c']
>>>
>>> for x in DATA:
... print(x)
a
b
c
Iterating Set:
>>> DATA = {'a', 'b', 'c'}
>>>
>>> for x in sorted(DATA):
... print(x)
a
b
c
12.1.1. Problem
>>> data = ['a', 'b', 'c']
>>> i = 0
>>>
>>> while i < len(data):
... x = data[i]
... print(x)
... i += 1
a
b
c
12.1.2. Solution
>>> data = ['a', 'b', 'c']
>>>
>>> for x in data:
... print(x)
a
b
c
12.1.3. Iterating Str
>>> DATA = 'abc'
>>>
>>> for x in DATA:
... print(x)
a
b
c
12.1.4. Iterating Tuple
>>> DATA = ('a', 'b', 'c')
>>>
>>> for x in DATA:
... print(x)
a
b
c
12.1.5. Iterating List
>>> DATA = ['a', 'b', 'c']
>>>
>>> for x in DATA:
... print(x)
a
b
c
12.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
12.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
12.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
12.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)
12.1.10. Recap
Iterating works for builtin sequences
Works with:
str
,bytes
,list
,tuple
,set
,dict
Naming Current Element:
letter
,digit
,number
,user
,color
,sentence
Iterating Str:
>>> DATA = 'abc'
>>>
>>> for x in DATA:
... print(x)
a
b
c
Iterating Tuple:
>>> DATA = ('a', 'b', 'c')
>>>
>>> for x in DATA:
... print(x)
a
b
c
Iterating List:
>>> DATA = ['a', 'b', 'c']
>>>
>>> for x in DATA:
... print(x)
a
b
c
Iterating Set:
>>> DATA = {'a', 'b', 'c'}
>>>
>>> for x in sorted(DATA):
... print(x)
a
b
c
12.1.11. Assignments
# %% About
# - Name: For About Count
# - Difficulty: easy
# - Lines: 7
# - Minutes: 5
# %% 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
# %% English
# 1. Count occurrences of each color in `DATA`
# 2. Define `red: int` with number of occurrences of string "red" in `DATA`
# 3. Define `green: int` with number of occurrences of string "green" in `DATA`
# 4. Define `blue: int` with number of occurrences of string "blue" in `DATA`
# 5. Use `for` loop
# 6. Do not use `list.count()`
# 7. Run doctests - all must succeed
# %% Polish
# 1. Zlicz wystąpienia każdego z kolorów w `DATA`
# 2. Zdefiniuj zmienną `red` z liczbą wystąpień ciągu znaków "red" w `DATA`
# 3. Zdefiniuj zmienną `green` z liczbą wystąpień ciągu znaków "green" w `DATA`
# 4. Zdefiniuj zmienną `blue` z liczbą wystąpień ciągu znaków "blue" w `DATA`
# 5. Użyj pętli `for`
# 6. Nie używaj `list.count()`
# 7. Uruchom doctesty - wszystkie muszą się powieść
# %% Example
# red = 3
# green = 2
# blue = 2
# %% Doctests
"""
>>> 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
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
red: int
green: int
blue: int
# %% Data
DATA = ['red', 'green', 'blue', 'red', 'green', 'red', 'blue']
red = 0
green = 0
blue = 0
# %% Result
# %% About
# - Name: For About Counter
# - Difficulty: easy
# - Lines: 5
# - Minutes: 5
# %% 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
# %% English
# 1. Count occurrences of each color in `DATA`
# 2. Define `result: dict`:
# - key: color name (str)
# - value: number of occurrences (int)
# 3. Use `for` loop to iterate over `DATA`
# 4. Do not use `list.count()`
# 5. Run doctests - all must succeed
# %% Polish
# 1. Zlicz wystąpienia każdego z kolorów w `DATA`
# 2. Zdefiniuj `result: dict`:
# - klucz: nazwa koloru (str)
# - wartość: liczba wystąpień (int)
# 3. Użyj pętli `for` do iterowania po `DATA`
# 4. Nie używaj `list.count()`
# 5. Uruchom doctesty - wszystkie muszą się powieść
# %% Example
# {'red': 3, 'green': 2, 'blue': 2}
# %% 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
# %% Doctests
"""
>>> 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}
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
result: dict[str,int]
# %% Data
DATA = ['red', 'green', 'blue', 'red', 'green', 'red', 'blue']
# %% Result
result = ...
# %% About
# - Name: For About Segmentation
# - Difficulty: easy
# - Lines: 10
# - Minutes: 8
# %% 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
# %% English
# 1. Count numbers in ranges (lower included, upper excluded)
# 2. Define `small: int` - with count of numbers between 0 and 3
# 3. Define `medium: int` - with count of numbers between 3 and 7
# 4. Define `large: int` - with count of numbers between 7 and 10
# 5. Use `for` loop to iterate over `DATA`
# 6. Run doctests - all must succeed
# %% Polish
# 1. Zlicz liczby w przedziałach (dolny włącznie, górny rozłącznie)
# 2. Zdefiniuj `small: int` - liczba wystąpień liczb pomiędzy 0 i 3
# 3. Zdefiniuj `medium: int` - liczba wystąpień liczb pomiędzy 3 i 7
# 4. Zdefiniuj `large: int` - liczba wystąpień liczb pomiędzy 7 i 10
# 5. Użyj pętli `for` do iterowania po `DATA`
# 6. Uruchom doctesty - wszystkie muszą się powieść
# %% Example
# {'small': 16, 'medium': 19, 'large': 15}
# %% Doctests
"""
>>> 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}
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
result: dict[str,int]
# %% Data
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,
]
# %% Result
result = {'small': 0, 'medium': 0, 'large': 0}
# %% About
# - Name: For About Newlines
# - Difficulty: easy
# - Lines: 2
# - Minutes: 5
# %% 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
# %% English
# 1. Join lines from `DATA` with newline character `\n`
# 2. Define `result: str` with the result
# 3. Use `for` loop to iterate over `DATA`
# 4. Do not use `str.join()`
# 5. Run doctests - all must succeed
# %% Polish
# 1. Złącz linie z `DATA` za pomocą znaku końca linii `\n`
# 2. Zdefiniuj `result: str`z wynikiem
# 3. Użyj pętli `for` do iterowania po `DATA`
# 4. Nie używaj `str.join()`
# 5. Uruchom doctesty - wszystkie muszą się powieść
# %% Example
# ('Nobody expects the Spanish Inquisition!\n'
# 'Our chief weapon is surprise.\n'
# ...
# 'Fear and surprise.\n')
# %% Hints
# - POSIX defines a line as a string with a newline at the end
# - `str += str` - increment add operator
# %% References
# [1] Monty Python
# The Spanish Inquisition
# Year: 1970
# Retrieved: 2025-02-27
# URL :https://people.csail.mit.edu/paulfitz/spanish/script.html
# %% Doctests
"""
>>> 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')
4
>>> pprint(result)
('Nobody expects the Spanish Inquisition!\\n'
'Our chief weapon is surprise.\\n'
'Surprise and fear.\\n'
'Fear and surprise.\\n')
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
result: str
# %% Data
DATA = [
'Nobody expects the Spanish Inquisition!',
'Our chief weapon is surprise.',
'Surprise and fear.',
'Fear and surprise.'
]
# %% Result
result = ...
# %% About
# - Name: For About Remove PL Chars
# - Difficulty: easy
# - Lines: 2
# - Minutes: 5
# %% 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
# %% English
# 1. Convert polish characters in `DATA` to their counterparts without "accents"
# 2. If letter is in `PL` then use conversion value as letter
# 3. Define `result: str` with the result
# 4. Use `for` to iterate over `DATA`
# 5. Add letter to `result`
# 6. Run doctests - all must succeed
# %% Polish
# 1. Przekonwertuj polskie znaki w `DATA` na ich odpowiedniki bez "ogonków"
# 2. Jeżeli litera jest w `PL` to użyj przekonwertowanej wartości jako litera
# 3. Zdefiniuj `result: str` z wynikiem
# 4. Użyj pętli `for`
# 5. Dodaj literę do `result`
# 6. Uruchom doctesty - wszystkie muszą się powieść
# %% Example
# 'zazolc gesla jazn'
# %% Doctests
"""
>>> 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'
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
result: str
# %% Data
PL = {
'ą': 'a',
'ć': 'c',
'ę': 'e',
'ł': 'l',
'ń': 'n',
'ó': 'o',
'ś': 's',
'ż': 'z',
'ź': 'z',
}
DATA = 'zażółć gęślą jaźń'
# %% Result
result = ...
# %% About
# - Name: For About Months
# - Difficulty: easy
# - Lines: 4
# - Minutes: 5
# %% 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
# %% 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ść
# %% Example
# {1: 'January',
# 2: 'February',
# 3: 'March',
# ...
# 11: 'November',
# 12: 'December'}
# %% Doctests
"""
>>> 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'}
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
result: dict[int,str]
# %% Data
MONTHS = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
# %% Result
result = ...
# %% About
# - Name: For About Endswith
# - Difficulty: easy
# - Lines: 5
# - Minutes: 5
# %% 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
# %% English
# 1. Define `result: list` with email addresses from `DATA`,
# having domain name mentioned in `DOMAINS`
# 2. Domain name is a part of the email address after `@` character
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj `result: list` z adresami email z `DATA`,
# mającymi domenę wymienioną w `DOMAINS`
# 2. Nazwa domeny to część adresu email po znaku `@`
# 3. Uruchom doctesty - wszystkie muszą się powieść
# %% Example
# ['alice@example.com',
# 'bob@example.com',
# ...
# 'mallory@example.net']
# %% Why
# - Check if you can filter data
# - Check if you know string methods
# - Check if you know how to iterate over list[dict]
# %% Doctests
"""
>>> 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)
['alice@example.com',
'bob@example.com',
'carol@example.com',
'mallory@example.net']
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% Imports
# %% Types
result: list[str]
# %% Data
DATA = [
{'name': 'Alice', 'email': 'alice@example.com'},
{'name': 'Bob', 'email': 'bob@example.com'},
{'name': 'Carol', 'email': 'carol@example.com'},
{'name': 'Dave', 'email': 'dave@example.org'},
{'name': 'Eve', 'email': 'eve@example.org'},
{'name': 'Mallory', 'email': 'mallory@example.net'},
]
DOMAINS = ('example.com', 'example.net')
# %% Result
result = ...