4.10. Idiom Reduce¶
Reduce sequence using function
Built-in
>>> 1 + 2
3
>>> 1 + 2 + 3 + 4
10
4.10.1. Syntax¶
functools.reduce(function, iterable[, initializer])
required
callable
- Functionrequired
iterable
- Sequence or iterator object
4.10.2. Problem¶
>>> def add(x, y):
... return x + y
>>>
>>>
>>> DATA = [1, 2, 3, 4]
>>> result = 0
>>>
>>> for element in DATA:
... result = add(result, element)
>>>
>>> print(result)
10
4.10.3. Solution¶
>>> from functools import reduce
>>>
>>>
>>> def add(x, y):
... return x + y
>>>
>>>
>>> DATA = [1, 2, 3, 4]
>>>
>>> reduce(add, DATA)
10
4.10.4. Rationale¶
>>> from functools import reduce
>>> from operator import mul
>>>
>>>
>>> DATA = [1, 2, 3, 4]
>>>
>>> reduce(mul, DATA)
24
>>> from functools import reduce
>>>
>>>
>>> DATA = [1, 2, 3, 4]
>>>
>>> reduce(min, DATA)
1
>>> reduce(max, DATA)
4
4.10.5. Map Reduce¶

4.10.6. Assignments¶
"""
* Assignment: Idiom Reduce Chain
* Required: yes
* Complexity: easy
* Lines of code: 4 lines
* Time: 3 min
English:
1. Use `range()` to get numbers:
a. from 0 (inclusive)
b. to 10 (exclusive)
2. Redefine `result` with odd numbers from `result`
3. Redefine `result` with cubed numbers from `result`
4. Redefine `result` with evaluated `result`
5. At the end `result` must be a `list` type
6. Run doctests - all must succeed
Polish:
1. Użyj `range()` aby otrzymać liczby:
a. od 0 (włącznie)
b. do 10 (rozłącznie)
2. Przedefiniuj `result` z nieparzystymi liczbami z `result`
3. Przedefiniuj `result` z podniesionymi do sześcianiu liczbami z `result`
4. Przedefiniuj `result` z ewaluaownym `result`
5. Na końcu `result` musi być typu `list`
6. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* range()
* map()
* filter()
* list()
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isfunction
>>> assert isfunction(odd), \
'Object `odd` must be a function'
>>> assert isfunction(cube), \
'Object `cube` must be a function'
>>> assert result is not Ellipsis, \
'Assign result to variable: `result`'
>>> assert type(result) is list, \
'Variable `result` has invalid type, should be list'
>>> assert all(type(x) is int for x in result), \
'All rows in `result` should be int'
>>> result
[1, 27, 125, 343, 729]
"""
def odd(x):
return x % 2
def cube(x):
return x ** 3
# Range from 0 to 10 (exclusive)
# type: Iterator[int]
result = ...
# Filter odd numbers
# type: Iterator[int]
result = ...
# Cube result
# type: Iterator[int]
result = ...
# Get list of results
# type: list[int]
result = ...
"""
* Assignment: Idiom Reduce Evaluate
* Required: yes
* Complexity: easy
* Lines of code: 2 lines
* Time: 3 min
English:
1. Define `result: float` with arithmetic mean of `DATA`
2. Note, that all the time you are working on a data stream
3. Run doctests - all must succeed
Polish:
1. Zdefiniuj `result: float` ze średnią arytmetyczną z `DATA`
2. Zwróć uwagę, że cały czas pracujesz na strumieniu danych
3. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* type cast to `list()` to expand generator before calculating mean
* `mean = sum(...) / len(...)`
* TypeError: object of type 'map' has no len()
* ZeroDivisionError: division by zero
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isfunction
>>> assert isfunction(odd), \
'Object `odd` must be a function'
>>> assert isfunction(cube), \
'Object `cube` must be a function'
>>> assert result is not Ellipsis, \
'Assign result to variable: `result`'
>>> assert type(result) is float, \
'Variable `result` has invalid type, should be float'
>>> result
245.0
"""
def odd(x):
return x % 2
def cube(x):
return x ** 3
DATA = range(0, 10)
DATA = filter(odd, DATA)
DATA = map(cube, DATA)
# Calculate mean of DATA
# type: float
result = ...
"""
* Assignment: Idiom Reduce Chain
* Complexity: easy
* Lines of code: 5 lines
* Time: 5 min
English:
1. Define `result` with numbers from `range()`:
a. from 0 (inclusive)
b. to 10 (exclusive)
2. Use `filter()` to get odd numbers from `result`
(and assign to `result`)
3. Use `map()` to cube all numbers in `result`
4. Create `result: float` with arithmetic mean of `result`
5. Do not use `lambda` expressions
6. Note, that all the time you are working on one data stream
7. Run doctests - all must succeed
Polish:
1. Zdefiniu `result` z liczbami z `range()`:
a. od 0 (włącznie)
b. do 10 (rozłącznie)
2. Użyj `filter()` aby otrzymać liczby nieparzyste z `result`
(i przypisz je do `result`)
3. Użyj `map()` aby podnieść wszystkie liczby w `result` do sześcianu
4. Stwórz `result: float` ze średnią arytmetyczną z `result`
5. Nie używaj wyrażeń lambda
6. Zwróć uwagę, że cały czas pracujesz na jednym strumieniu danych
7. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* type cast to `list()` to expand generator before calculating mean
* `mean = sum(...) / len(...)`
* TypeError: object of type 'map' has no len()
* ZeroDivisionError: division by zero
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isfunction
>>> isfunction(odd)
True
>>> isfunction(cube)
True
>>> type(result) is float
True
>>> result
245.0
"""
def odd(x):
return x % 2
def cube(x):
return x ** 3
# Range numbers from 0 to 10 (exclusive)
# Filter odd numbers
# Cube result
# Calculate mean
# type: float
result = ...