驴C贸mo filtrar una lista en Python?

Rate this post

驴C贸mo se puede filtrar una lista en Python utilizando una condici贸n arbitraria? La forma m谩s pit贸nica y m谩s eficiente es utilizar la comprensi贸n de lista [x for x in list if condition] para filtrar todos los elementos de una lista.

Filtrar con comprensi贸n de lista

La forma m谩s pit贸nica de filtrar una lista, en mi opini贸n, es la declaraci贸n de comprensi贸n de lista [x for x in list if condition]. Puedes sustituir la condici贸n por cualquier funci贸n de x que quieras utilizar como condici贸n de filtrado.

Por ejemplo, si quieres filtrar todos los elementos menores de, digamos, 10, utilizar铆as la declaraci贸n de comprensi贸n de lista [x for x in list if x<10] para crear una nueva lista con todos los elementos de la lista menores de 10.

Aqu铆 hay tres ejemplos de filtrado de una lista:

  • Obtener elementos menores de ocho: [x for x in lst if x<8].
  • Obtener elementos pares: [x for x in lst if x%2==0].
  • Obtener elementos impares: [x for x in lst if x%2].
lst = [8, 2, 6, 4, 3, 1]

# Filter all elements <8
small = [x for x in lst if x<8]
print(small)


# Filter all even elements
even = [x for x in lst if x%2==0]
print(even)

# Filter all odd elements
odd = [x for x in lst if x%2]
print(odd)

El resultado es:

# Elements <8
[2, 6, 4, 3, 1]

# Even Elements
[8, 2, 6, 4]

# Odd Elements
[3, 1]

Esta es la forma m谩s eficiente de filtrar una lista y tambi茅n la m谩s pit贸nica. Pero si buscas alternativas, sigue leyendo porque te explicar茅 todos y cada uno de los matices del filtrado de listas en Python en esta completa gu铆a.

Filtrar una lista en Python con filter()

La funci贸n filter(function, iterable) toma como entrada una funci贸n que recibe un argumento (un elemento de lista) y devuelve un valor booleano sobre si este elemento de lista debe pasar el filtro. Todos los elementos que pasan el filtro se devuelven como un nuevo objeto iterable (un objeto filter).

Puedes emplear una declaraci贸n de funci贸n lambda para crear la funci贸n justo donde la pasas como argumento. La sintaxis de la funci贸n lambda es lambda x: expression y significa que utilizas x como argumento de entrada y devuelves expression como resultado (que puede o no utilizar x para decidir sobre el valor de retorno). Para m谩s informaci贸n, consulta mi art铆culo detallado del blog sobre la funci贸n lambda.

lst = [8, 2, 6, 4, 3, 1]

# Filter all elements <8
small = filter(lambda x: x<8, lst)
print(list(small))


# Filter all even elements
even = filter(lambda x: x%2==0, lst)
print(list(even))

# Filter all odd elements
odd = filter(lambda x: x%2, lst)
print(list(odd))

El resultado es:

# Elements <8
[2, 6, 4, 3, 1]

# Even Elements
[8, 2, 6, 4]

# Odd Elements
[3, 1]

La funci贸n filter() devuelve un objeto filter que es iterable. Para convertirlo en una lista, se utiliza el constructor list(...).

Art铆culo relacionado:

Filtrar una lista en Python con map()

S贸lo a帽ado esta opci贸n porque hay gente que a煤n intenta utilizar la funci贸n map() para filtrar elementos de una lista. Est谩 claro que esta es la forma incorrecta de hacerlo. La raz贸n es que la funci贸n map() s贸lo le permite transformar cada elemento de una lista en un nuevo elemento. Pero seguir谩s teniendo el mismo n煤mero de elementos en la lista. Por lo tanto, necesitas un paso adicional para filtrar todos los elementos (por ejemplo, utilizando comprensi贸n de lista). Pero si est谩s dispuesto a dar este paso adicional, tambi茅n podr铆as haber utilizado una comprensi贸n de lista para filtrar desde un principio.

A esto me refiero:

lst = [8, 2, 6, 4, 3, 1]

# Filter all elements <8
small = list(map(lambda x: x if x<8 else None, lst))
small = [x for x in small if x!=None]
print(small)


# Filter all even elements
even = list(map(lambda x: x if x%2==0 else None, lst))
even = [x for x in even if x!=None]
print(even)


# Filter all odd elements
odd = list(map(lambda x: x if x%2 else None, lst))
odd = [x for x in odd if x!=None]
print(odd)

El resultado vuelve a ser el mismo:

[2, 6, 4, 3, 1]
[8, 2, 6, 4]
[3, 1]

Pero el m茅todo para obtener este resultado es claramente ineficaz y no resulta legible.

Art铆culos Relacionados:

Filtrar una lista en Python con generador

Una expresi贸n generadora crea un iterador sobre una secuencia de valores. Funciona igual que la comprensi贸n de listas, pero sin crear un tipo de datos de lista. Esto es un poco m谩s eficiente.

Puedes utilizar expresiones generadoras en cualquier llamada a una funci贸n que requiera un iterable como entrada. Por ejemplo, si quieres calcular la suma de todos los valores que cumplen una determinada condici贸n en una lista.

  • Primero, determina el iterable de valores que cumplen una determinada condici贸n.
  • En segundo lugar, suma todos esos valores con la funci贸n sum().

Aqu铆 tienes un ejemplo de c贸digo que muestra c贸mo sumar todos los valores enteros de una lista (e ignorar el resto) utilizando una expresi贸n generadora para filtrar los no enteros:

lst = [6, 8, 2, 8, 'Alice']
print(sum(x for x in lst if type(x) == int))
# 24

Comprueba el type(x) de cada elemento y comp谩ralo con el tipo integer. Esta comparaci贸n devuelve True si el elemento es, de hecho, de tipo entero.

Filtrar una lista en Python con condici贸n

Puedes definir cualquier condici贸n compleja sobre un elemento de la lista para decidir si se filtra o no. S贸lo tienes que crear tu propia funci贸n (por ejemplo, condition(x)) que tome un elemento de la lista como entrada y devuelva el valor booleano True si se cumple la condici贸n o False en caso contrario.

Aqu铆 tienes un ejemplo de c贸digo:

def condition(x):
    '''Define your arbitrarily
    complicated condition here'''

    return x<10 and x>0

lst = [11, 14, 3, 0, -1, -3]

# Filter out all elements that do
# not meet condition
filtered = [x for x in lst if condition(x)]
print(filtered)
# [3]

Todos los elementos que son menores que 10 y mayores que 0 se incluyen en la lista filtrada. Por lo tanto, solo queda el elemento 3.

Filtrar una lista en Python con condiciones m煤ltiples

Lo mismo se aplica si quieres combinar varias condiciones. Digamos que deseas filtrar todos los elementos x>9 y x<1. Estas son dos condiciones (simples). Puedes definir cualquier condici贸n compleja sobre un elemento de la lista para decidir si se filtra o no. S贸lo tienes que crear tu propia funci贸n (por ejemplo, condition(x)) que tome un elemento de la lista como entrada y devuelva el valor booleano True si se cumple la condici贸n o False en caso contrario.

Aqu铆 est谩 el mismo ejemplo de c贸digo que antes:

def condition(x):
    '''Define your arbitrarily
    complicated condition here'''

    return x<10 and x>0

lst = [11, 14, 3, 0, -1, -3]

# Filter out all elements that do
# not meet condition
filtered = [x for x in lst if condition(x)]
print(filtered)
# [3]

Todos los elementos que son menores que 10 y mayores que 0 se incluyen en la lista filtrada. Por lo tanto, solo queda el elemento 3.

Filtrar una lista en Python con Regex

Problema: Dada una lista de cadenas. 驴C贸mo puedes filtrar aquellas que coincidan con una determinada expresi贸n regular?

Ejemplo: Digamos que tienes una lista ['Alice', 'Anne', 'Ann', 'Tom'] y quieres descartar los elementos que no cumplen el patr贸n regex 'A.*e'. Esperas que la lista filtrada sea ['Alice', 'Anne'].

Soluci贸n: Utiliza el marco de filtrado de comprensi贸n de lista [x for x in list if match] para filtrar todos los elementos que no concuerden con una cadena determinada.

import re

# Define the list and the regex pattern to match
customers = ['Alice', 'Anne', 'Ann', 'Tom']
pattern = 'A.*e'

# Filter out all elements that match the pattern
filtered = [x for x in customers if re.match(pattern, x)]

print(filtered)
# ['Alice', 'Anne']

Utiliza el m茅todo re.match() que devuelve un objeto match si hay una coincidencia o None en caso contrario. En Python, cualquier objeto match se eval煤a como True (si es necesario), salvo algunas excepciones (por ejemplo, None, 0, 0.0, etc.). Si necesitas refrescar tus conocimientos b谩sicos sobre la funci贸n re.match(), echa un vistazo a mi detallado art铆culo del blog que te lleva paso a paso por esta potente herramienta de Python.

Art铆culos Relacionados:

驴C贸mo filtrar una lista de listas en Python?

Respuesta corta: Para filtrar una lista de listas por una condici贸n en las listas internas, utiliza la declaraci贸n de comprensi贸n de lista [x for x in list if condition(x)] y sustituye condition(x) por tu condici贸n de filtrado que devuelva True para incluir la lista interna x, y False en caso contrario.

Las listas pertenecen a las estructuras de datos m谩s importantes de Python: 隆todo programador experto las conoce a fondo! Sorprendentemente, incluso los programadores intermedios no saben la mejor manera de filtrar una lista, y mucho menos una lista de listas en Python. 隆Este tutorial te muestra c贸mo hacer esto 煤ltimo!

Problema: Digamos que tienes una lista de listas. Quieres filtrar la lista de listas para que s贸lo queden las listas interiores que satisfagan una determinada condici贸n. La condici贸n es una funci贸n de la lista interna, como la media o la suma de los elementos de la lista interna.

Ejemplo: Dada la siguiente lista de listas con mediciones semanales de temperatura, y una lista interior semanal.

# Measurements of a temperature sensor (7 per week)
temperature = [[10, 8, 9, 12, 13, 7, 8], # week 1
              [9, 9, 5, 6, 6, 9, 11], # week 2
              [10, 8, 8, 5, 6, 3, 1]] # week 3

驴C贸mo filtrar las semanas m谩s fr铆as con un valor medio de temperatura <8? Este es el resultado que deseas:

print(cold_weeks)
# [[9, 9, 5, 6, 6, 9, 11], [10, 8, 8, 5, 6, 3, 1]]

Hay dos m茅todos sem谩nticamente equivalentes para lograr esto: la comprensi贸n de listas y la funci贸n map().

Art铆culos Relacionados:

Filtrar una lista de cadenas en Python

Problema: Dada una lista de cadenas y una cadena de b煤squeda. 驴C贸mo puedes filtrar las que contienen la cadena de b煤squeda?

Ejemplo: Digamos que tienes una lista ['Alice', 'Anne', 'Ann', 'Tom'] y quieres obtener todos los elementos que contienen la subcadena 'An'. Esperas que la lista filtrada sea ['Anne', 'Ann'].

Soluci贸n: Utiliza el esquema de filtrado de comprensi贸n de lista [x for x in list if condition] para descartar todos los elementos que no contengan otra cadena.

import re

# Define the list
customers = ['Alice', 'Anne', 'Ann', 'Tom']

# Filter out all elements that contain 'An'
filtered = [x for x in customers if 'An' in x]

print(filtered)
# ['Anne', 'Ann']

Utiliza la operaci贸n b谩sica de pertenencia a la cadena “in” para comprobar si un elemento pasa el filtro o no.

Filtrar una lista en Python para eliminar cadenas vac铆as

Problema: Dada una lista de cadenas. 驴C贸mo puedes eliminar todas las cadenas vac铆as?

Ejemplo: Digamos que tienes una lista ['Alice', 'Anne', '', 'Ann', '', 'Tom'] y quieres obtener una nueva lista ['Alice', 'Anne', 'Ann', 'Tom'] de cadenas no vac铆as.

Soluci贸n: Utiliza el esquema de filtrado de comprensi贸n de lista [x for x in list if x] para filtrar todas las cadenas vac铆as.

import re

# Define the list
customers = ['Alice', 'Anne', '', 'Ann', '', 'Tom']

# Filter out all elements that contain 'An'
filtered = [x for x in customers if x]

print(filtered)
# ['Alice', 'Anne', 'Ann', 'Tom']

Aprovechas la caracter铆stica de que Python asigna el valor booleano False a la cadena vac铆a ''.

Filtrar una lista en Python con endswith() y startswith()

Problema: Dada una lista de cadenas. 驴C贸mo puedes filtrar aquellas que comienzan con otra cadena (o terminan con otra cadena)? En otras palabras, deseas obtener todas las cadenas que tienen otra cadena como prefijo o sufijo.

Ejemplo: Digamos que tienes una lista ['Alice', 'Anne', 'Ann', 'Tom'] y quieres obtener todos los elementos que empiezan por 'An'. Esperas que la lista filtrada sea ['Anne', 'Ann'].

Soluci贸n: Utiliza el esquema de filtrado de comprensi贸n de lista [x for x in list if x.startswith('An')] para filtrar todos los elementos que empiezan por 'An'. Si deseas comprobar cadenas que terminan con otra cadena, puedes usar la funci贸n str.endswith() en su lugar.

import re

# Define the list
customers = ['Alice', 'Anne', 'Ann', 'Tom']

# Filter out all elements that start with 'An'
filtered = [x for x in customers if x.startswith('An')]

print(filtered)
# ['Anne', 'Ann']


# Filter out all elements that end with 'e'
filtered = [x for x in customers if x.endswith('e')]

print(filtered)
# ['Alice', 'Anne']

Utiliza las funciones startswith() y endswith() como condiciones de filtrado.

Filtrar una lista en Python con lambda

La funci贸n filter(function, iterable) toma como argumento una funci贸n de filtrado que toma un elemento de la lista como entrada y devuelve el valor booleano True si se cumple la condici贸n o False en caso contrario. Esta funci贸n decide si un elemento se incluye en la lista filtrada o no.

Para definir esta funci贸n, puedes utilizar la palabra clave lambda. La funci贸n lambda es una funci贸n an贸nima: piensa en ella como una funci贸n desechable que s贸lo se necesita como argumento y para nada m谩s en el c贸digo.

Este es el c贸digo que muestra c贸mo utilizar la funci贸n lambda para filtrar una lista y devolver s贸lo los valores impares de la lista:

# Create the list
lst = [1, 2, 3, 4]

# Get all odd values
print(list(filter(lambda x: x%2, lst)))
# [1, 3]

La funci贸n lambda x: x%2 toma un argumento x -el elemento que hay que comprobar con el filtro- y devuelve el resultado de la expresi贸n x%2. Esta expresi贸n de m贸dulo devuelve 1 si el entero es impar y 0 si es par. Por lo tanto, todos los elementos impares pasan la prueba.

Filtrar una lista en Python con otra lista

Problema: Dada una lista de valores lst y una lista de booleanos filter. 驴C贸mo filtrar la primera lista usando la segunda lista? M谩s espec铆ficamente, quieres crear una nueva lista que incluya el i-茅simo elemento de lst si el i-茅simo elemento de filter es True.

Ejemplo: Aqu铆 hay dos listas de ejemplo:

lst = [1, 2, 3, 4]
filter_lst = [True, False, False, True]

Y deseas obtener esta lista:

[1, 4]

Soluci贸n: Utiliza una simple declaraci贸n de comprensi贸n de lista [lst[i] for i in range(len(lst)) if filter_lst[i]] que compruebe para cada 铆ndice i si el valor booleano del filtro correspondiente es True. En este caso, se a帽ade el elemento en el 铆ndice i en lst a la nueva lista filtrada. Este es el c贸digo:

lst = [1, 2, 3, 4]
filter_lst = [True, False, False, True]

res = [lst[i] for i in range(len(lst)) if filter_lst[i]]
print(res)
# [1, 4]

La lista booleana sirve de “m谩scara” que determina qu茅 elemento pasa el filtro y cu谩l no.

Una alternativa es usar la funci贸n zip() para iterar sobre m煤ltiples secuencias sin necesidad de tocar ning煤n 铆ndice:

lst = [1, 2, 3, 4]
filter_lst = [True, False, False, True]

res = [x for (x, boo) in zip(lst, filter_lst) if boo]
print(res)
# [1, 4]

驴Necesitas mejorar tu comprensi贸n de zip()? 隆Echa un vistazo a nuestro exhaustivo art铆culo del blog!

Filtrar una lista en Python con 铆ndices

Problema: dada una lista de valores y una lista de 铆ndices. 驴C贸mo filtrar todos los elementos con 铆ndices en la segunda lista?

Ejemplo: Tienes la lista ['Alice', 'Bob', 'Ann', 'Frank'] y los 铆ndices [1, 2]. Lo que est谩s buscando es la lista filtrada ['Bob', 'Ann'].

Soluci贸n: Recorre todos los 铆ndices de la segunda lista e incluye los elementos correspondientes de la lista mediante una simple sentencia de comprensi贸n de lista [lst[i] for i in indices].

lst = ['Alice', 'Bob', 'Ann', 'Frank']
indices = [1, 2]

res = [lst[i] for i in indices]
print(res)
# ['Bob', 'Ann']

Solo dos elementos con 铆ndices 1 y 2 pasan el filtro.

Filtrar en Python una lista de diccionarios

Problema: Dada una lista de diccionarios. Cada diccionario consta de uno o m谩s pares (clave, valor). Quieres filtrarlos por el valor de una determinada clave del diccionario (atributo). 驴C贸mo puedes lograrlo?

Ejemplo minimalista: Considera el siguiente ejemplo en el que tienes tres diccionarios de usuarios con las claves username, age y play_time. Quieres obtener una lista de todos los usuarios que cumplen una determinada condici贸n, como play_time > 100. Esto es lo que intentas conseguir:

users = [{'username': 'alice', 'age': 23, 'play_time': 101},
        {'username': 'bob', 'age': 31, 'play_time': 88},
        {'username': 'ann', 'age': 25, 'play_time': 121},]

superplayers = # Filtering Magic Here

print(superplayers)

El resultado deber铆a parecerse a esto, donde el atributo play_time determina si un diccionario pasa el filtro o no, es decir, play_time>100:

[{'username': 'alice', 'age': 23, 'play_time': 101},
{'username': 'ann', 'age': 25, 'play_time': 121}]

Soluci贸n: Utiliza la comprensi贸n de lista [x for x in lst if condition(x)] para crear una nueva lista de diccionarios que cumplan la condici贸n. Todos los diccionarios en lst que no cumplen con la condici贸n se filtran. Puedes definir tu propia condici贸n sobre el elemento x de la lista.

Aqu铆 tienes el c贸digo que te muestra c贸mo filtrar todos los diccionarios de usuario que no cumplen la condici贸n de haber jugado al menos 100 horas.

users = [{'username': 'alice', 'age': 23, 'play_time': 101},
        {'username': 'bob', 'age': 31, 'play_time': 88},
        {'username': 'ann', 'age': 25, 'play_time': 121},]

superplayers = [user for user in users if user['play_time']>100]

print(superplayers)

La salida es la lista filtrada de diccionarios que cumplen la condici贸n:

[{'username': 'alice', 'age': 23, 'play_time': 101},
{'username': 'ann', 'age': 25, 'play_time': 121}]

Art铆culos relacionados en el blog de Finxter:

Filtrar en Python elementos 煤nicos en una lista – eliminar duplicados

驴C贸mo eliminar todos los duplicados de un valor dado en la lista?

El enfoque ingenuo es revisar cada elemento y verificar si este elemento ya existe en la lista. Si es as铆, ret铆ralo. Sin embargo, esto requiere unas cuantas l铆neas de c贸digo.

Una forma m谩s corta y concisa es crear un diccionario a partir de los elementos de la lista. Cada elemento de la lista se convierte en una nueva clave del diccionario. Todos los elementos que aparezcan varias veces se asignar谩n a la misma clave. El diccionario s贸lo contiene claves 煤nicas, no puede haber varias claves iguales.

Como valores del diccionario, simplemente tomas valores ficticios (por defecto).

Art铆culos relacionados del blog:

Luego, s贸lo tienes que volver a convertir el diccionario en una lista, desechando los valores ficticios. Como las claves del diccionario permanecen en el mismo orden, no se pierde la informaci贸n de orden de los elementos de la lista original.

Este es el c贸digo:

>>> lst = [1, 1, 1, 3, 2, 5, 5, 2]
>>> dic = dict.fromkeys(lst)
>>> dic
{1: None, 3: None, 2: None, 5: None}
>>> duplicate_free = list(dic)
>>> duplicate_free
[1, 3, 2, 5]

Filtrar en Python un rango en una lista

Filtrar todos los elementos de una lista que est茅n dentro del rango de valores entre los 铆ndices de start y stop dados.

lst = [3, 10, 3, 2, 5, 1, 11]
start, stop = 2, 9

filtered_lst = [x for x in lst if x>=start and x<=stop]
print(filtered_lst)
# [3, 3, 2, 5]

Empleas la condici贸n x>=start y x<=stop para comprobar si la lista de elementos x est谩 dentro del rango [start, stop] o no.

Filtrar en Python una lista con mayor que y menor que

Filtrar todos los elementos de una lista que sean mayores que un valor determinado y.

lst = [3, 10, 3, 2, 5, 1, 11]
y = 2

filtered_lst = [x for x in lst if x>y]
print(filtered_lst)
# [3, 10, 3, 5, 11]

Utiliza la condici贸n x > y para comprobar si el elemento de lista x es mayor que y o no. En el primer caso, se incluye en la lista filtrada. En el 煤ltimo, no.

Puedes utilizar la misma idea con el operador menor que < mediante la declaraci贸n de comprensi贸n de lista [x for x in lst if x<y].

Recuento de listas filtradas en Python

驴C贸mo puedes contar elementos bajo una determinada condici贸n en Python? Por ejemplo, 驴qu茅 pasa si quieres contar todos los valores pares de una lista? 驴O todos los n煤meros primos? 驴O todas las cadenas que comienzan con un determinado car谩cter? Hay m煤ltiples formas de conseguirlo, vamos a discutirlas una por una.

Digamos que tienes una condici贸n para cada elemento x. Convirt谩mosla en una funci贸n con el nombre condition(x). Puedes definir cualquier condici贸n que quieras, s贸lo tienes que ponerla en tu funci贸n. Por ejemplo, esta condici贸n devuelve True para todos los elementos que son mayores que el entero 10:

def condition(x):
    return x > 10


print(condition(10))
# False

print(condition(2))
# False

print(condition(11))
# True

Pero tambi茅n puedes definir condiciones m谩s complicadas, como comprobar si son n煤meros primos.

Recuento de listas en Python con if

驴C贸mo puedes contar los elementos de la lista SI se cumple la condici贸n?

La respuesta es utilizar una simple expresi贸n generadora sum(condition(x) for x in lst):

>>> def condition(x):
    return x>10

>>> lst = [10, 11, 42, 1, 2, 3]
>>> sum(condition(x) for x in lst)
2

El resultado indica que hay dos elementos que son m谩s grandes que 10. Has utilizado una expresi贸n generadora que devuelve un iterador de booleanos. Ten en cuenta que el booleano True se representa con el valor entero 1 y el booleano False se representa con el valor entero 0. Por eso puedes calcular simplemente la suma de todos los booleanos para obtener el n煤mero de elementos para los que se cumple la condici贸n.

Recuento de listas en Python con mayor / menor que

Si quieres determinar el n煤mero de elementos que son mayores o menores que un valor especificado, s贸lo tienes que modificar la condici贸n de este ejemplo:

>>> def condition(x):
    return x>10

>>> lst = [10, 11, 42, 1, 2, 3]
>>> sum(condition(x) for x in lst)
2

Por ejemplo, para encontrar el n煤mero de elementos menores que 5, usa la condici贸n x<5 en la expresi贸n del generador:

>>> lst = [10, 11, 42, 1, 2, 3]
>>> sum(x<5 for x in lst)
3

Recuento de listas en Python de cero / no cero

Para contar el n煤mero de ceros en una lista dada, usa la llamada al m茅todo list.count(0).

Para contar el n煤mero de no-ceros en una lista dada, debes utilizar el recuento condicional, tal y como se coment贸 anteriormente:

def condition(x):
    return x!=0

lst = [10, 11, 42, 1, 2, 0, 0, 0]
print(sum(condition(x) for x in lst))
# 5

Recuento de listas en Python con lambda + map

Una alternativa es utilizar una combinaci贸n de las funciones map y lambda.

Art铆culos Relacionados:

Este es el c贸digo:

>>> sum(map(lambda x: x%2==0, [1, 2, 3, 4, 5]))
2

Cuenta el n煤mero de enteros pares en la lista.

  • La funci贸n lambda devuelve un valor booleano para un elemento dado x.
  • La funci贸n map transforma cada elemento de lista en un valor booleano (1 o 0).
  • La funci贸n sum suma los “1”.

El resultado es el n煤mero de elementos para los que la condici贸n se eval煤a como True.

Filtrar una lista por longitud de cadena en Python

Dada una lista de cadenas. 驴C贸mo obtener todos los elementos que tienen m谩s de x caracteres? En otras palabras: 驴c贸mo filtrar una lista por longitud de cadena?

coders = ['Ann', 'Alice', 'Frank', 'Pit']
filtered = [x for x in coders if len(x)>3]
print(filtered)
# ['Alice', 'Frank']

La sentencia de comprensi贸n de lista [x for x in coders if len(x)>3] filtra todas las cadenas que tienen m谩s de tres caracteres.

Filtrar los elementos None de una lista en Python

驴C贸mo eliminar todos los valores None de una lista? Por ejemplo, tienes la lista ['Alice', None, 'Ann', None, None, 'Bob'] y quieres la lista ['Alice', 'Ann', 'Bob']. 驴C贸mo puedes lograrlo?

coders = ['Alice', None, 'Ann', None, None, 'Bob']
filtered = [x for x in coders if x]
print(filtered)
# ['Alice', 'Ann', 'Bob']

En Python, cada elemento tiene un valor booleano asociado, por lo que puede usar cualquier objeto Python como condici贸n. El valor None est谩 asociado al valor booleano False.

Filtrar en Python una lista JSON

Problema: Digamos que tienes un objeto de lista JSON. Quieres filtrar la lista en funci贸n de un atributo. 驴C贸mo lograrlo?

Ejemplo: Dada la siguiente lista JSON.

json = [
    {
        "user": "alice",
        "type": "free"
    },
    {
        "user": "ann",
        "type": "paid"
    },
    {
        "user": "bob",
        "type": "paid"
    }
]

Quieres encontrar todos los usuarios que tienen un tipo de cuenta 'paid'.

[
    {
        "user": "ann",
        "type": "paid"
    },
    {
        "user": "bob",
        "type": "paid"
    }
]

Soluci贸n: Utiliza la comprensi贸n de lista [x for x in json if x['type']=='paid'] para filtrar la lista y obtener una nueva lista json con los objetos que pasan el filtro.

json = [
    {
        "user": "alice",
        "type": "free"
    },
    {
        "user": "ann",
        "type": "paid"
    },
    {
        "user": "bob",
        "type": "paid"
    }
]

filtered = [x for x in json if x['type']=='paid']
print(filtered)
# [{'user': 'ann', 'type': 'paid'},
#  {'user': 'bob', 'type': 'paid'}]

S贸lo Ann y Bob tienen una cuenta de pago y pasan el test x['type']=='paid'.

Filtrar en una l铆nea una lista en Python

驴Quieres filtrar tu lista por una condici贸n dada en una l铆nea de c贸digo? Utiliza la declaraci贸n de comprensi贸n de lista [x for x in list if condition], en la que la parte de la condici贸n puede ser cualquier expresi贸n booleana sobre x. Esta sentencia de una sola l铆nea devuelve un nuevo objeto de lista con todos los elementos que pasan el “test” de filtrado.

Aqu铆 hay un ejemplo:

lst = ['Alice', 3, 5, 'Bob', 10]

# ONE-LINER:
f = [x for x in lst if type(x)==str]

print(f)
# ['Alice', 'Bob']

La sentencia filtra todos los elementos de la lista y comprueba si son de tipo cadena. Si lo son, pasan la prueba y se incluyen en la nueva lista.

Si te gustan las sentencias de una sola l铆nea, te encantar谩 mi libro Python One-Liner (NoStarch Press 2020). Te muestra exactamente c贸mo escribir c贸digo pit贸nico y comprimir tu pensamiento y codificaci贸n a la forma m谩s minimalista.

C贸mo filtrar una lista en Python de forma eficiente: filter() frente a comprensi贸n de lista

[Spoiler] 驴Qu茅 es m谩s r谩pido para filtrar una lista: filter() o comprensi贸n de lista? Para listas grandes con un mill贸n de elementos, filtrar listas con comprensi贸n de lista es un 40% m谩s r谩pido que el m茅todo incorporado filter().

Para responder a esta pregunta, he escrito un breve script que comprueba el rendimiento en tiempo de ejecuci贸n del filtrado de grandes listas de tama帽os crecientes mediante los m茅todos filter() y de comprensi贸n de lista.

Mi tesis es que el m茅todo de comprensi贸n de lista deber铆a ser ligeramente m谩s r谩pido para los tama帽os de lista m谩s grandes, porque aprovecha la eficiente implementaci贸n de cPython de la comprensi贸n de lista y no necesita llamar a una funci贸n adicional.

Utilic茅 mi port谩til con un procesador Intel(R) Core(TM) i7-8565U a 1,8 GHz (con Turbo Boost hasta 4,6 GHz) y 8 GB de RAM.

A continuaci贸n, cre茅 100 listas con ambos m茅todos con tama帽os que iban de 10.000 elementos a 1.000.000 de elementos. Como elementos, simplemente increment茅 los n煤meros enteros en uno a partir de 0.

Este es el c贸digo que he utilizado para medir y representar los resultados: 驴qu茅 m茅todo es m谩s r谩pido: filter() o una comprensi贸n de lista?

import time


# Compare runtime of both methods
list_sizes = [i * 10000 for i in range(100)]
filter_runtimes = []
list_comp_runtimes = []

for size in list_sizes:

    lst = list(range(size))
   
    # Get time stamps
    time_0 = time.time()
    list(filter(lambda x: x%2, lst))
    time_1 = time.time()
    [x for x in lst if x%2]
    time_2 = time.time()

    # Calculate runtimes
    filter_runtimes.append((size, time_1 - time_0))
    list_comp_runtimes.append((size, time_2 - time_1))


# Plot everything
import matplotlib.pyplot as plt
import numpy as np

f_r = np.array(filter_runtimes)
l_r = np.array(list_comp_runtimes)

print(filter_runtimes)
print(list_comp_runtimes)

plt.plot(f_r[:,0], f_r[:,1], label='filter()')
plt.plot(l_r[:,0], l_r[:,1], label='list comprehension')

plt.xlabel('list size')
plt.ylabel('runtime (seconds)')

plt.legend()
plt.savefig('filter_list_comp.jpg')
plt.show()

El c贸digo compara los tiempos de ejecuci贸n de la funci贸n filter() y la variante de comprensi贸n de lista para filtrar una lista. Ten en cuenta que la funci贸n filter() devuelve un objeto filter, por lo que debes convertirlo en lista mediante el constructor list().

Aqu铆 est谩 el gr谩fico resultante que compara el tiempo de ejecuci贸n de los dos m茅todos. En el eje x, puedes ver el tama帽o de la lista de 0 a 1.000.000 de elementos. En el eje y, puedes ver el tiempo de ejecuci贸n que se necesita en segundos para ejecutar las respectivas funciones.

El gr谩fico resultante muestra que ambos m茅todos son extremadamente r谩pidos para unas decenas de miles de elementos. De hecho, son tan r谩pidos que la funci贸n time() del m贸dulo time no puede capturar el tiempo transcurrido.

Pero a medida que aumentas el tama帽o de las listas a cientos de miles de elementos, el m茅todo de comprensi贸n de lista empieza a ganar:

Para listas grandes con un mill贸n de elementos, filtrar listas con comprensi贸n de lista es un 40% m谩s r谩pido que el m茅todo incorporado filter().

El motivo es la eficiente implementaci贸n de la declaraci贸n de comprensi贸n de lista. Sin embargo, es interesante la siguiente observaci贸n. Si no conviertes la funci贸n filter en una lista, obtendr谩s el siguiente resultado:

De repente, la funci贸n filter() tiene un tiempo de ejecuci贸n constante cercano a 0 segundos, independientemente del n煤mero de elementos que haya en la lista. 驴Por qu茅 est谩 pasando esto?

La explicaci贸n es simple: la funci贸n filter devuelve un iterador, no una lista. El iterador no necesita calcular un solo elemento hasta que se le pida que calcule el elemento next(). Por lo tanto, la funci贸n filter() calcula el siguiente elemento s贸lo si es necesario hacerlo. S贸lo si lo conviertes en lista, tendr谩 que computar todos los valores. De lo contrario, no calcula de antemano ning煤n valor.

A d贸nde ir desde aqu铆

Este tutorial te ha mostrado los entresijos de la funci贸n filter() en Python y la ha comparado con el m茅todo de comprensi贸n de lista para filtrar: [x for x in list if condition]. Has podido comprobar que esto 煤ltimo no s贸lo es m谩s legible y m谩s pit贸nico, sino tambi茅n m谩s r谩pido. 隆As铆 que adopta el enfoque de comprensi贸n de lista para filtrar listas!

Si te encanta programar y quieres hacerlo a tiempo completo desde la comodidad de tu propia casa, est谩s de suerte:

He creado un seminario web gratuito que muestra c贸mo comenc茅 como freelancer de Python despu茅s de mis estudios de inform谩tica trabajando desde casa (y viendo crecer a mis hijos) mientras ganaba un ingreso a tiempo completo trabajando solo horas a tiempo parcial.

Seminario web: 驴C贸mo convertirse en un freelance de Python de seis cifras?

脷nete a 21.419 codificadores ambiciosos de Python. Es divertido!