Operaciones de acumulación con reduce()#

  • Última modificación: Mayo 14, 2022

Adaptado del libro “Mastering Large Datasets with Python”.

Suma de una lista#

[1]:
integers = list(range(5))
integers
[1]:
[0, 1, 2, 3, 4]
[2]:
from functools import reduce
from operator import add

reduce(
    add,  # function
    integers,  # iterable
    0,  # initializer
)
[2]:
10

Acumulador personalizado#

[3]:
def my_add(acc, nxt):
    return acc + nxt


reduce(
    my_add,  # function
    integers,  # iterable
    0,  # initializer
)
[3]:
10

Operación de la función de acumulación#

[4]:
acc = 0  # initializer

acc = integers[0] + acc
acc = integers[1] + acc
acc = integers[2] + acc
acc = integers[3] + acc
acc = integers[4] + acc
acc
[4]:
10

Uso de lambda#

[5]:
reduce(
    lambda acc, nxt: acc + nxt,
    integers,
    0,
)
[5]:
10

Acumulación sobre estructuras de datos#

[6]:
my_list = [
    {"a": 1, "b": 4},
    {"a": 3, "b": 2},
    {"a": 0, "b": 1},
    {"a": 2, "b": 0},
    {"a": 4, "b": 3},
]

reduce(lambda acc, nxt: acc + nxt.get("a", 0), my_list, 0)
[6]:
10
[7]:
reduce(lambda acc, nxt: acc + nxt.get("a", 0), my_list, 0.0)
[7]:
10.0
[8]:
def make_sums(acc, nxt):
    acc["a"] = acc.get("a", 0) + nxt["a"]
    acc["b"] = acc.get("b", 0) + nxt["b"]
    return acc


reduce(
    make_sums,
    my_list,
    {},
)
[8]:
{'a': 10, 'b': 10}

Equivalente a filter()#

[9]:
my_list = list(range(10))
my_list
[9]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[10]:
def keep_if_even(acc, nxt):
    if nxt % 2 == 0:
        return acc + [nxt]
    return acc


reduce(
    keep_if_even,
    my_list,
    [],
)
[10]:
[0, 2, 4, 6, 8]

Conteos de frecuencia con reduce()#

[11]:
my_list = list("ANCADACCAEDAD")
my_list
[11]:
['A', 'N', 'C', 'A', 'D', 'A', 'C', 'C', 'A', 'E', 'D', 'A', 'D']
[12]:
def make_counts(acc, nxt):
    acc[nxt] = acc.get(nxt, 0) + 1
    return acc


reduce(
    make_counts,
    my_list,
    {},
)
[12]:
{'A': 5, 'N': 1, 'C': 3, 'D': 3, 'E': 1}