Articles

Cómo usar la función de filtro de Python

Introducción

La función incorporada de Python filter() puede usarse para crear un nuevo iterador a partir de un iterable existente (como una lista o un diccionario) que filtrará eficientemente los elementos usando una función que nosotros proporcionemos. Un iterable es un objeto de Python sobre el que se puede «iterar», es decir, que devolverá elementos en una secuencia tal que podemos utilizarlo en un bucle for.

La sintaxis básica de la función filter() es:

filter(function, iterable)

Esta devolverá un objeto filtro, que es un iterable. Podemos utilizar una función como list() para hacer una lista de todos los elementos devueltos en un objeto filtro.

La función filter() proporciona una forma de filtrar valores que a menudo puede ser más eficiente que una comprensión de lista, especialmente cuando estamos empezando a trabajar con conjuntos de datos más grandes. Por ejemplo, una comprensión de lista hará una nueva lista, lo que aumentará el tiempo de ejecución de ese procesamiento. Esto significa que después de que nuestra comprensión de lista haya completado su expresión, tendremos dos listas en memoria. Sin embargo, filter() hará un objeto simple que contiene una referencia a la lista original, la función proporcionada, y un índice de dónde ir en la lista original, que ocupará menos memoria.

En este tutorial, revisaremos cuatro formas diferentes de utilizar filter(): con dos estructuras iterables diferentes, con una función lambda y sin función definida.

Usando filter() con una función

El primer argumento de filter() es una función, que usamos para decidir si incluir o filtrar cada elemento. La función se llama una vez por cada elemento del iterable que se pasa como segundo argumento y cada vez que devuelve False, se elimina el valor. Como este argumento es una función, podemos pasar una función normal o podemos hacer uso de funciones lambda, sobre todo cuando la expresión es menos compleja.

A continuación se muestra la sintaxis de un lambda con filter():

filter(lambda item: item expression, iterable)

Con una lista, como la siguiente, podemos incorporar una función lambda con una expresión contra la que queremos evaluar cada elemento de la lista:

creature_names = 

Para filtrar esta lista y encontrar los nombres de las criaturas de nuestro acuario que empiezan por vocal, podemos ejecutar la siguiente función lambda:

print(list(filter(lambda x: x.lower() in 'aeiou', creature_names)))

Aquí declaramos un elemento de nuestra lista como x. Luego configuramos nuestra expresión para acceder al primer carácter de cada cadena (o carácter «cero»), así x. Bajando las mayúsculas y minúsculas de cada uno de los nombres nos aseguramos de que esto coincida con las letras de la cadena de nuestra expresión, 'aeiou'.

Finalmente pasamos el iterable creature_names. Al igual que en el apartado anterior aplicamos list() al resultado para crear una lista a partir del iterador filter() devuelve.

El resultado será el siguiente:

Output

Este mismo resultado se puede conseguir utilizando una función que definamos:

creature_names = def names_vowels(x): return x.lower() in 'aeiou'filtered_names = filter(names_vowels, creature_names)print(list(filtered_names))

Nuestra función names_vowels define la expresión que implementaremos para filtrar creature_names.

De nuevo, el resultado sería el siguiente:

Output

En general, las funciones lambda consiguen el mismo resultado con filter() que cuando utilizamos una función regular. La necesidad de definir una función regular crece a medida que aumenta la complejidad de las expresiones para filtrar nuestros datos, lo que probablemente promueva una mejor legibilidad en nuestro código.

Usando None con filter()

Podemos pasar None como primer argumento a filter() para que el iterador devuelto filtre cualquier valor que Python considere «falso». Generalmente, Python considera que cualquier cosa con una longitud de 0 (como una lista vacía o una cadena vacía) o numéricamente equivalente a 0 es falsa, de ahí el uso del término «falso.»

En el siguiente caso queremos filtrar nuestra lista para que sólo se muestren los números de los tanques de nuestro acuario:

aquarium_tanks = , {}]

En este código tenemos una lista que contiene enteros, secuencias vacías y un valor booleano.

filtered_tanks = filter(None, aquarium_tanks)

Usamos la función filter() con None y pasamos la lista aquarium_tanks como nuestro iterable. Como hemos pasado None como primer argumento, comprobaremos si los elementos de nuestra lista se consideran falsos.

print(list(filtered_tanks))

Entonces envolvemos filtered_tanks en una función list() para que nos devuelva una lista para filtered_tanks al imprimir.

Aquí la salida muestra sólo los enteros. Todos los elementos que se evaluaron con False, que son equivalentes a 0 en longitud, fueron eliminados por filter():

Output

Nota: Si no utilizamos list() e imprimimos filtered_tanks recibiríamos un objeto filtro algo así: <filter object at 0x7fafd5903240>. El objeto filtro es un iterable, por lo que podríamos hacer un bucle sobre él con for o podemos usar list() para convertirlo en una lista, cosa que hacemos aquí porque es una buena forma de revisar los resultados.

Con None hemos utilizado filter() para eliminar rápidamente los elementos de nuestra lista que se consideraban falsos.

Usando filter() con una lista de diccionarios

Cuando tenemos una estructura de datos más compleja, podemos seguir usando filter() para evaluar cada uno de los elementos. Por ejemplo, si tenemos una lista de diccionarios, no sólo queremos iterar sobre cada elemento de la lista -uno de los diccionarios- sino que también podemos querer iterar sobre cada par clave:valor de un diccionario para evaluar todos los datos.

Como ejemplo, digamos que tenemos una lista de cada criatura de nuestro acuario junto con diferentes detalles sobre cada una de ellas:

aquarium_creatures = 

Queremos filtrar estos datos por una cadena de búsqueda que le damos a la función. Para que filter() acceda a cada diccionario y a cada elemento de los diccionarios, construimos una función anidada, como la siguiente:

def filter_set(aquarium_creatures, search_string): def iterator_func(x): for v in x.values(): if search_string in v: return True return False return filter(iterator_func, aquarium_creatures)

Definimos una función filter_set() que toma como parámetros aquarium_creatures y search_string. En filter_set() pasamos nuestro iterator_func() como función a filter(). La función filter_set() devolverá el iterador resultante de filter().

El iterator_func() toma como argumento x, que representa un elemento de nuestra lista (es decir, un único diccionario).

A continuación, el bucle for accede a los valores de cada par clave:valor de nuestros diccionarios y luego utiliza una sentencia condicional para comprobar si el search_string está en v, representando un valor.

Al igual que en nuestros ejemplos anteriores, si la expresión evalúa a True la función añade el elemento al objeto filtro. Esto devolverá una vez que la función filter_set() haya finalizado. Colocamos return False fuera de nuestro bucle para que compruebe cada elemento de cada diccionario, en lugar de devolver después de comprobar sólo el primer diccionario.

Llamamos a filter_set() con nuestra lista de diccionarios y la cadena de búsqueda para la que queremos encontrar coincidencias:

filtered_records = filter_set(aquarium_creatures, "2") 

Una vez completada la función tenemos nuestro objeto filtro almacenado en la variable filtered_records, que convertimos en una lista e imprimimos:

print(list(filtered_records)) 

Recibiremos la siguiente salida de este programa:

Output

Hemos filtrado la lista de diccionarios con la cadena de búsqueda 2. Podemos ver que se han devuelto los tres diccionarios que incluían un número de depósito con 2. El uso de nuestra propia función anidada nos ha permitido acceder a cada elemento y cotejar eficientemente cada uno de ellos con la cadena de búsqueda.

Conclusión

En este tutorial, hemos aprendido las diferentes formas de utilizar la función filter() en Python. Ahora puedes usar filter() con tu propia función, una función lambda, o con None para filtrar elementos en estructuras de datos de distinta complejidad.

Aunque en este tutorial imprimimos los resultados de filter() inmediatamente en formato de lista, es probable que en nuestros programas utilicemos el objeto filter() devuelto y manipulemos más los datos.

Si quieres aprender más Python, consulta nuestra serie Cómo codificar en Python 3 y nuestra página de temas de Python.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *