9.9. Idiom Recap

  • Python for loop is equivalent to forEach in other languages

  • Other languages for loop is Python's while (sic!)

Code Complexity vs. Programmer Experience:

../../_images/iterator-patterns-programmer-exp.png

Time Complexity: https://wiki.python.org/moin/TimeComplexity

9.9.1. Foreach Element

Problem:

>>> data = ['a', 'b', 'c']
>>>
>>> i = 0
>>> while i < len(data):
...     x = data[i]
...     i += 1
...     print(x)
a
b
c

Solution:

>>> data = ['a', 'b', 'c']
>>>
>>> for x in data:
...     print(x)
a
b
c

9.9.2. Foreach Index

Problem:

>>> data = ['a', 'b', 'c']
>>>
>>> for i in range(len(data)):
...     x = data[i]
...     print(x)
a
b
c

Solution:

>>> data = ['a', 'b', 'c']
>>>
>>> for x in data:
...     print(x)
a
b
c

9.9.3. Range

  • Do something multiple times

Problem:

>>> i = 0
>>> while i < 3:
...     print('hello')
...     i += 1
hello
hello
hello

Solution:

>>> for _ in range(3):
...     print('hello')
hello
hello
hello

9.9.4. Sum

Problem:

>>> data = [1, 2, 3]
>>>
>>> result = 0
>>> for value in data:
...     result += value

Solution:

>>> data = [1, 2, 3]
>>>
>>> result = sum(data)

9.9.5. Enumerate

Problem:

>>> data = ['a', 'b', 'c']
>>>
>>> index = 0
>>> for value in data:
...     print(index, value)
...     index += 1
0 a
1 b
2 c

Solution:

>>> data = ['a', 'b', 'c']
>>>
>>> for index, value in enumerate(data):
...     print(index, value)
0 a
1 b
2 c

9.9.6. Zip

Problem:

>>> data1 = ['a', 'b', 'c']
>>> data2 = [1, 2, 3]
>>>
>>> count = min(len(data1), len(data2))
>>> result = []
>>> for i in range(count):
...     a = data1[i]
...     b = data2[i]
...     result.append((a, b))

Solution:

>>> data1 = ['a', 'b', 'c']
>>> data2 = [1, 2, 3]
>>>
>>> result = zip(data1, data2)

9.9.7. Any

Problem:

>>> users = [
...     {'firstname': 'Alice', 'lastname': 'Apricot', 'age': 30},
...     {'firstname': 'Bob', 'lastname': 'Blackthorn', 'age': 31},
...     {'firstname': 'Carol', 'lastname': 'Corn', 'age': 32},
...     {'firstname': 'Dave', 'lastname': 'Durian', 'age': 33},
...     {'firstname': 'Eve', 'lastname': 'Elderberry', 'age': 34},
...     {'firstname': 'Mallory', 'lastname': 'Melon', 'age': 15},
... ]
>>>
>>> result = True
>>> for user in users:
...     if not user['age']>=18:
...         result = False
>>>
>>> if result:
...     print('All users are adult')
... else:
...     print('We have at least one child')
...
We have at least one child

Solution:

>>> users = [
...     {'firstname': 'Alice', 'lastname': 'Apricot', 'age': 30},
...     {'firstname': 'Bob', 'lastname': 'Blackthorn', 'age': 31},
...     {'firstname': 'Carol', 'lastname': 'Corn', 'age': 32},
...     {'firstname': 'Dave', 'lastname': 'Durian', 'age': 33},
...     {'firstname': 'Eve', 'lastname': 'Elderberry', 'age': 34},
...     {'firstname': 'Mallory', 'lastname': 'Melon', 'age': 15},
... ]
>>>
>>> if all(user['age']>=18 for user in users):
...     print('All users are adult')
... else:
...     print('We have at least one child')
...
We have at least one child

9.9.8. List Comprehension

Problem:

>>> data = ['a', 'b', 'c']
>>>
>>> result = []
>>> for x in data:
...     result.append(x)

Solution:

>>> data = ['a', 'b', 'c']
>>>
>>> result = [x for x in data]

9.9.9. Set Comprehension

Problem:

>>> data = ['a', 'b', 'c']
>>>
>>> result = set()
>>> for x in data:
...     result.add(x)

Solution:

>>> data = ['a', 'b', 'c']
>>>
>>> result = {x for x in data}

9.9.10. Dict Comprehension

Problem:

>>> data = {'a': 1, 'b': 2, 'c': 3}
>>>
>>> result = {}
>>> for key, value in data.items():
...     result[key] = value

Solution:

>>> data = {'a': 1, 'b': 2, 'c': 3}
>>>
>>> result = {k:v for k,v in data.items()}

9.9.11. For Else

  • x in data

Problem:

>>> data = [1, 2, 3]
>>> x = 10
>>>
>>> found = False
>>> for value in data:
...     if value == x:
...         print('Found')
...         found = True
...         break
>>> if not found:
...     print('Not Found')
Not Found

Solution:

>>> data = [1, 2, 3]
>>> x = 10
>>>
>>> for value in data:
...     if value == x:
...         print('Found')
...         break
... else:
...     print('Not Found')
Not Found

9.9.12. While Else

  • x in data

Problem:

>>> data = [1, 2, 3]
>>> x = 10
>>>
>>> found = False
>>> while i < len(data):
...     value = data[i]
...     i += 1
...     if value == x:
...         print('Found')
...         found = True
...         break
>>> if not found:
...     print('Not Found')
Not Found

Solution:

>>> data = [1, 2, 3]
>>> x = 10
>>>
>>> while i < len(data):
...     value = data[i]
...     i += 1
...     if value == x:
...         print('Found')
...         break
... else:
...     print('Not Found')
Not Found

9.9.13. Str Startswith One

Problem:

>>> data = 'alice@example.com'
>>>
>>> data[:5] == 'alice'
True

Solution:

>>> data = 'alice@example.com'
>>>
>>> data.startswith('alice')
True

9.9.14. Str Startswith Many

Problem:

>>> data = 'alice@example.com'
>>>
>>> data[:5] == 'alice' or data[:3] == 'bob'
True

Solution:

>>> data = 'alice@example.com'
>>>
>>> data.startswith(('alice', 'bob'))
True

9.9.15. Str Endswith One

Problem:

>>> data = 'alice@example.com'
>>>
>>> data[-11:] == 'example.com'
True

Solution:

>>> data = 'alice@example.com'
>>>
>>> data.endswith('example.com')
True

9.9.16. Str Endswith Many

Problem:

>>> data = 'alice@example.com'
>>>
>>> data[-11:] == 'example.com' or data[-11:] == 'example.edu'
True

Solution:

>>> data = 'alice@example.com'
>>>
>>> data.endswith(('example.com', 'example.edu'))
True

9.9.17. Join Strings with Character

Problem:

>>> data = ['Alice', 'Bob', 'Carol']
>>>
>>> result = ''
>>> for user in data:
...     result += user + ','
>>> result = result.removesuffix(',')

Solution:

>>> data = ['Alice', 'Bob', 'Carol']
>>>
>>> result = ','.join(data)

9.9.18. Join Lines with Newlines

Problem:

>>> data = ['line1', 'line2', 'line3']
>>>
>>> result = [line+'\n' for line in data]

Solution:

>>> data = ['line1', 'line2', 'line3']
>>>
>>> result = '\n'.join(data) + '\n'

9.9.19. Map

Problem:

>>> def transform(x):
...     return ...
...
>>> data = [1, 2, 3]
>>>
>>> result = [transform(x) for x in data]

Solution:

>>> def transform(x):
...     return ...
...
>>> data = [1, 2, 3]
>>>
>>> result = map(transform, data)

9.9.20. Filter

Problem:

>>> def predicate(x):
...     return ...
...
>>> data = [1, 2, 3]
>>>
>>> result = [x for x in data if predicate(x)]

Solution:

>>> def predicate(x):
...     return ...
...
>>> data = [1, 2, 3]
>>>
>>> result = filter(predicate, data)

9.9.21. Other Programming Languages

For:

for (int i = 0; i <= 10; i++)  # C/C++/Java
for (var i = 0; i <= 10; i++)  # JavaScript

i = 0
while i <= 10:  #  Python
    i += 1

ForEach Index:

for (let idx in collection)         # JavaScript
for idx in range(len(collection))   # Python

ForEach Element:

for (var element : collection)   # Java
for (let element of collection)  # JavaScript
for element in collection        # Python
for i in range(0,10)             # Python

Enumerate:

for (int i = 0; i <= collection.length; i++)  # C++ / JAVA / JavaScript
    element = collection[i]

for (let i in collection)  # JavaScript
    element = collection[i]

for i in range(len(collection)):  # Python (1to1 algorithm conversion)
    element = collection[i]

for i, element in enumerate(collection)  # Python (Pythonic way)

Zip:

for (int i = 0; i <= collection.length; i++)  # C++ / JAVA / JavaScript
    a = collection1[i]
    b = collection2[i]

for i in range(len(collection1)):  # Python (1to1 algorithm conversion)
    a = collection1[i]
    b = collection2[i]

for a, b in zip(collection1, collection2)  # Python (Pythonic way)

9.9.22. Assignments

# %% About
# - Name: Idiom Recap Signum
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% 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 function `signum() -> int|float`
# 2. Function takes one argument `value: int|float`
# 3. Function returns a value `value` limited
#    to the range `-1.0 <= value <= 1.0`
# 4. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj funkcję `signum() -> int`
# 2. Funkcja przyjmuje jeden argument `value: int`
# 3. Funkcja zwraca wartość `value` ograniczoną
#    do zakresu `MIN <= value <= MAX`
# 4. Uruchom doctesty - wszystkie muszą się powieść

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> result = signum(1)

>>> assert result is not Ellipsis, \
'Assign result to function: `signum`'

>>> assert result is not None, \
'Function: `signum` must return a value'

>>> assert type(result) is int, \
'Function: `signum` must return a int'

>>> signum(-1.0001)
-1

>>> signum(-1.0000)
-1

>>> signum(-0.9999)
-0.9999

>>> signum(-0.0001)
-0.0001

>>> signum(0.0000)
0.0

>>> signum(0.0001)
0.0001

>>> signum(0.9999)
0.9999

>>> signum(1.0000)
1

>>> signum(1.0001)
1

>>> signum(10)
1

>>> signum(-10)
-1
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`

# %% Imports

# %% Types
from typing import Callable
signum: Callable[[int|float], int|float]

# %% Data

# %% Result
def signum(value):
    ...

# %% About
# - Name: Idiom Recap MinMax
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% 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 function `minmax() -> int`
# 2. Function takes one argument `value: int`
# 3. Function returns a value `value` limited
#    to the range `MIN <= value <= MAX`
# 4. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj funkcję `minmax() -> int`
# 2. Funkcja przyjmuje jeden argument `value: int`
# 3. Funkcja zwraca wartość `value` ograniczoną
#    do zakresu `MIN <= value <= MAX`
# 4. Uruchom doctesty - wszystkie muszą się powieść

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> result = minmax(1)

>>> assert result is not Ellipsis, \
'Assign result to function: `minmax`'

>>> assert result is not None, \
'Function: `minmax` must return a value'

>>> assert type(result) is int, \
'Function: `minmax` must return a int'

>>> minmax(-1)
0

>>> minmax(0)
0

>>> minmax(1)
1

>>> minmax(9)
9

>>> minmax(10)
10

>>> minmax(11)
10
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`

# %% Imports

# %% Types
from typing import Callable
minmax: Callable[[int], int]

# %% Data
MIN = 0
MAX = 10

# %% Result
def minmax(value):
    ...

# %% About
# - Name: Idiom Recap SetPosition
# - Difficulty: easy
# - Lines: 3
# - Minutes: 3

# %% 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 function `set_position() -> tuple[int,int]`
# 2. Function takes two arguments `x: int` and `y: int`
# 3. Function returns a tuple `(x, y)` with values `x` and `y`
#    limited to the range `0 <= x <= 1920` and `0 <= y <= 1080`
# 4. Run doctests - all must succeed

# %% Polish
# 1. Zdefiniuj funkcję `set_position() -> tuple[int,int]`
# 2. Funkcja przyjmuje dwa argumenty `x: int` i `y: int`
# 3. Funkcja zwraca krotkę `(x, y)` z wartościami `x` i `y`
#    ograniczonymi do zakresu `0 <= x <= 1920` i `0 <= y <= 1080`
# 4. Uruchom doctesty - wszystkie muszą się powieść

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> result = set_position(1, 2)

>>> assert result is not Ellipsis, \
'Assign result to function: `set_position`'

>>> assert result is not None, \
'Function: `set_position` must return a value'

>>> assert type(result) is tuple, \
'Function: `set_position` must return a tuple'

>>> assert len(result) == 2, \
'Function: `set_position` must return 2 elements'

>>> assert type(result[0]) is int, \
'Function: `set_position` must return a tuple of integers'

>>> assert type(result[1]) is int, \
'Function: `set_position` must return a tuple of integers'

>>> set_position(0, 0)
(0, 0)

>>> set_position(1, 0)
(1, 0)

>>> set_position(0, 1)
(0, 1)

>>> set_position(-1, 0)
(0, 0)

>>> set_position(0, -1)
(0, 0)

>>> set_position(1920, 1080)
(1920, 1080)

>>> set_position(1921, 1080)
(1920, 1080)

>>> set_position(1920, 1081)
(1920, 1080)

>>> set_position(1919, 1080)
(1919, 1080)

>>> set_position(1920, 1079)
(1920, 1079)

>>> set_position(-1, 1081)
(0, 1080)

>>> set_position(1921, -1)
(1920, 0)

>>> set_position(1921, 1081)
(1920, 1080)

>>> set_position(-1, -1)
(0, 0)

>>> set_position(101, 102)
(101, 102)
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`

# %% Imports

# %% Types
from typing import Callable
set_position: Callable[[int, int], tuple[int, int]]

# %% Data
X_MIN = 0
X_MAX = 1920

Y_MIN = 0
Y_MAX = 1080

# %% Result
def set_position(x, y):
    ...