19 · Map, filter, reduce
Iteradores perezosos para transformar y filtrar secuencias — y cuándo una comprensión es la opción más pythónica.
`map(fn, iterable)` y `filter(pred, iterable)` devuelven **iteradores perezosos** — producen valores de uno en uno solo cuando se solicitan, por lo que nunca construyen la lista de salida completa en memoria. `functools.reduce` colapsa una secuencia en un único valor.
Sin esto:
Sin iteración perezosa, transformar un dataset de 1 millón de muestras en un paso asigna una copia completa en memoria. `map` y `filter` permiten encadenar transformaciones que transmiten datos sin materializar colecciones intermedias.
map(función, iterable) aplica función a cada elemento y devuelve un objeto map (iterador perezoso). Envuélvelo en list() para materializar el resultado. filter(predicado, iterable) conserva solo los elementos para los cuales el predicado devuelve verdadero. Ambos son perezosos — no evalúan nada hasta que los iteras. functools.reduce(función, iterable, inicial) aplica acumulativamente una función de dos argumentos para colapsar la secuencia en un único valor. Para la mayoría de las transformaciones y filtros del día a día, una comprensión de lista es más idiomática — pero map y filter brillan en pipelines donde quieres pereza y composabilidad.
Python (in browser)
`map()` devuelve un iterador, no una lista. Llamar `next()` sobre él extrae el siguiente valor transformado. Esta pereza significa que puedes aplicar `map` sobre un dataset de un millón de elementos sin copiarlo.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
`filter(None, iterable)` es una forma rápida de descartar valores falsos (0, string vacío, None, lista vacía). Encadenar `filter` seguido de `map` compone de forma perezosa — el pipeline completo corre bajo demanda.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
`reduce` aplica la función de forma acumulativa: `reduce(f, [a,b,c], init)` = `f(f(f(init, a), b), c)`. Para `sum`, `max` y `min` los built-ins son más rápidos y legibles. Reserva `reduce` para folds no estándar como la fusión de dicts.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
¿Qué tipo devuelve `map(str.upper, ['a', 'b'])`?
- `map(fn, iter)` y `filter(pred, iter)` devuelven iteradores perezosos — envuelve con `list()` para materializar. Componen sin costo sin copiar datos.
- `functools.reduce(fn, iter, init)` colapsa una secuencia en un valor. Usa los built-ins (`sum`, `max`, `min`) para los casos comunes — `reduce` para folds personalizados.
- Para transformaciones/filtros simples, una comprensión de lista es más idiomática y legible. Prefiere `map`/`filter` cuando la pereza o una función nombrada existente los hace la opción más limpia.
Pipelines de preprocesamiento perezosos: `map(preprocess, raw_samples)` transmite un dataset a través de una transformación sin cargarlo todo en memoria. Descartar filas inválidas: `filter(is_valid, dataset)`. Sumar gradientes entre workers: `reduce(np.add, worker_gradients)`. En PyTorch, los workers del `DataLoader` aplican transformaciones de forma perezosa — el mismo modelo de `map` sobre iterador.
Si lo quitas: Sin iteración perezosa, un pipeline de preprocesamiento que encadena varias transformaciones debe materializar una lista intermedia en cada paso — para un dataset de 500 000 imágenes esto podría significar gigabytes de copias innecesarias antes de que un solo batch llegue al modelo.