lista = [1,2,3,4] # utilizando un bucle lista_mapeada = [] for e in lista: lista_mapeada.append(f(e)) lista_filtrada = [] for e in lista: if f(e): lista_filtrada.append(e) # utilizando map y filter lista_mapeada = map(f, lista) lista_filtrada = filter(f, lista)En Python 2.0 se agregaron listas por comprensión, que ofrecen una sintaxis más intuitiva para las primitivas map y filter.
lista_mapeada = [f(e) for e in lista] lista_filtrada = [e for e in lista if f(e)]Si están familiarizados con lenguajes como Haskell, que utilizan evaluación lazy o perezosa conocen algunas de las ventajas de esta característica en un lenguaje de programación: la evaluación de algunas expresiones no se hace inmediatamente sino que se pospone hasta que el valor es realmente necesario.
En el contexto de las primitivas map y filter que nos conciernen, la ventaja de la evaluación lazy es que no se computan hasta tanto no se accede al contenido de las listas resultantes. Con esto en mente, en Python 2.4 se agregaron generadores por comprensión (simplemente remplazando los corchetes por paréntesis en la sintaxis anterior). El resultado es un generador: un objeto que se comporta parcialmente como una lista, dado que puede iterarse sobre el (aunque no puede indexarse y accededer directamente a su i-ésimo elemento).
gen_mapeado = (f(e) for e in lista) gen_filtrado = (e for e in lista if f(e))La mejora más inmediata es la performance: en lugar de aplicar la función completamente en el momento, no se hacen los cómputos requeridos hasta que se accede al resultado. Por esta razón, la librería estándar itertools incluye primitivas imap, ifilter y varias más que devuelven generadores en lugar de listas, puesto que en muchos casos este comportamiento es deseable.
En Python 3, sencillamente se cambió el comportamiento de las primitivas convencionales para que devuelvan iteradores en lugar de listas. Así, los nuevos map, filter, zip y compañía se comportan como los anteriores itertools.imap, iterators.ifilter y iterators.izip.
# Python 3 >>> l = map(f, [1,2,3,4]) >>> l[2] TypeError: object is unsubscriptableEl nuevo comportamiento no es compatible hacia atrás, pero puede resolverse esta diferencia sencillamente cambiando todas las llamadas map(l) (y los otros) por list(map(l)), lo cual produce un comportamiento casi idéntico en Python 3 y Python 2 (y digo casi porque si el map original devolvía una tupla o un string, pueden haber diferencias).