04-12-2022, 12:58 PM
¿Cómo filtrar una lista en Python?
<div><figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio">
<div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="¿Cómo filtrar una lista en Python?" width="780" height="439" src="https://www.youtube.com/embed/BoDmedffyuQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</figure>
<p>¿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 <a rel="noreferrer noopener" href="https://blog.finxter.com/list-comprehension/" data-type="post" data-id="1171" target="_blank">comprensión de lista</a> <code>[x for x in list if condition]</code> para filtrar todos los elementos de una lista. </p>
<h2>Filtrar con comprensión de lista</h2>
<p>La forma más pitónica de filtrar una lista, en mi opinión, es la declaración de comprensión de lista <code>[x for x in list if condition]</code>. Puedes sustituir la condición por cualquier función de <code>x</code> que quieras utilizar como condición de filtrado.</p>
<p>Por ejemplo, si quieres filtrar todos los elementos menores de, digamos, 10, utilizarías la declaración de comprensión de lista <code>[x for x in list if x<10]</code> para crear una nueva lista con todos los elementos de la lista menores de 10.</p>
<p>Aquí hay tres ejemplos de filtrado de una lista:</p>
<ul>
<li>Obtener elementos menores de ocho: <code>[x for x in lst if x<8]</code>.</li>
<li>Obtener elementos pares: <code>[x for x in lst if x%2==0]</code>.</li>
<li>Obtener elementos impares: <code>[x for x in lst if x%2]</code>.</li>
</ul>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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)</pre>
<p>El resultado es:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Elements <8
[2, 6, 4, 3, 1] # Even Elements
[8, 2, 6, 4] # Odd Elements
[3, 1]</pre>
<p>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.</p>
<h2>Filtrar una lista en Python con filter()</h2>
<p>La función <code>filter(function, iterable)</code> 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 <code><a href="https://blog.finxter.com/iterators-iterables-and-itertools/" data-type="post" data-id="29507" target="_blank" rel="noreferrer noopener">iterable</a></code> (un objeto filter).</p>
<p>Puedes emplear una declaración de función <code>lambda</code> 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 <a href="https://blog.finxter.com/a-simple-introduction-of-the-lambda-function-in-python/">artículo detallado del blog sobre la función lambda</a>.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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))</pre>
<p>El resultado es:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Elements <8
[2, 6, 4, 3, 1] # Even Elements
[8, 2, 6, 4] # Odd Elements
[3, 1]</pre>
<p>La función <code>filter()</code> devuelve un objeto filter que es iterable. Para convertirlo en una lista, se utiliza el constructor <code><a href="https://blog.finxter.com/python-list/" data-type="post" data-id="21502" target="_blank" rel="noreferrer noopener">list(...)</a></code>.</p>
<p><strong>Artículo relacionado:</strong></p>
<ul>
<li><a href="https://blog.finxter.com/how-to-filter-in-python-using-lambda-functions/">Cómo filtrar usando la función lambda</a></li>
</ul>
<h2>Filtrar una lista en Python con map()</h2>
<p>Sólo añado esta opción porque hay gente que aún intenta utilizar la función <code>map()</code> para filtrar elementos de una lista. Está claro que esta es la forma incorrecta de hacerlo. La razón es que la función <code><a href="https://blog.finxter.com/daily-python-puzzle-string-encrpytion-ord-function-map-function/" target="_blank" rel="noreferrer noopener">map()</a></code> 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 <a href="https://blog.finxter.com/list-to-dict-convert-a-list-into-a-dictionary-in-python/" target="_blank" rel="noreferrer noopener">comprensión de lista</a>). 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.</p>
<p>A esto me refiero:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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)</pre>
<p>El resultado vuelve a ser el mismo:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[2, 6, 4, 3, 1]
[8, 2, 6, 4]
[3, 1]</pre>
<p>Pero el método para obtener este resultado es claramente ineficaz y no resulta legible.</p>
<p><strong>Artículos Relacionados:</strong></p>
<ul>
<li><a href="https://blog.finxter.com/how-to-get-rid-of-pythons-map-function-with-list-comprehension/">Cómo deshacerse de la función <code>map()</code> (y por qué Guido la odiaba)</a></li>
</ul>
<h2>Filtrar una lista en Python con generador</h2>
<p>Una <a href="https://blog.finxter.com/how-to-use-generator-expressions-in-python-dictionaries/">expresión generadora</a> 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.</p>
<p>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.</p>
<ul>
<li>Primero, determina el iterable de valores que cumplen una determinada condición.</li>
<li>En segundo lugar, suma todos esos valores con la función <code><a href="https://blog.finxter.com/python-sum/" data-type="post" data-id="22221" target="_blank" rel="noreferrer noopener">sum()</a></code>.</li>
</ul>
<p>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:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">lst = [6, 8, 2, 8, 'Alice']
print(sum(x for x in lst if type(x) == int))
# 24</pre>
<p>Comprueba el <code><a href="https://blog.finxter.com/python-type/" data-type="post" data-id="23967" target="_blank" rel="noreferrer noopener">type(x)</a></code> de cada elemento y compáralo con el tipo integer. Esta comparación devuelve True si el elemento es, de hecho, de tipo entero.</p>
<h2>Filtrar una lista en Python con condición</h2>
<p>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, <code>condition(x)</code>) que tome un elemento de la lista como entrada y devuelva el valor booleano <code>True</code> si se cumple la condición o <code>False</code> en caso contrario.</p>
<p>Aquí tienes un ejemplo de código:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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]</pre>
<p>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.</p>
<h2>Filtrar una lista en Python con condiciones múltiples</h2>
<p>Lo mismo se aplica si quieres combinar varias condiciones. Digamos que deseas filtrar todos los elementos <code>x>9</code> y <code>x<1</code>. 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, <code>condition(x)</code>) 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.</p>
<p>Aquí está el mismo ejemplo de código que antes:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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]</pre>
<p>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.</p>
<h2>Filtrar una lista en Python con Regex</h2>
<p><strong>Problema</strong>: Dada una lista de cadenas. ¿Cómo puedes filtrar aquellas que coincidan con una determinada <a href="https://blog.finxter.com/python-regex/">expresión regular</a>?</p>
<p><strong>Ejemplo</strong>: Digamos que tienes una lista <code>['Alice', 'Anne', 'Ann', 'Tom']</code> y quieres descartar los elementos que no cumplen el patrón regex <code>'A.*e'</code>. Esperas que la lista filtrada sea <code>['Alice', 'Anne']</code>.</p>
<p><strong>Solución</strong>: Utiliza el marco de filtrado de comprensión de lista <code>[x for x in list if match]</code> para filtrar todos los elementos que no concuerden con una cadena determinada.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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']</pre>
<p>Utiliza el método <code>re.match()</code> 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, <code>None</code>, 0, 0.0, etc.). Si necesitas refrescar tus conocimientos básicos sobre la función <code>re.match()</code>, echa un vistazo a mi detallado <a href="https://blog.finxter.com/python-regex-match/">artículo del blog</a> que te lleva paso a paso por esta potente herramienta de Python.</p>
<p><strong>Artículos Relacionados:</strong></p>
<ul>
<li><a href="https://blog.finxter.com/python-how-to-count-elements-in-a-list-matching-a-condition/">Cómo contar elementos de una lista que coincidan con una condición</a></li>
<li><a href="https://blog.finxter.com/how-to-match-an-exact-word-in-python-regex-answer-dont/">Cómo hacer coincidir una palabra exacta en Python</a></li>
<li><a href="https://blog.finxter.com/python-regex-how-to-count-the-number-of-matches/">Cómo contar el número de coincidencias en Python</a></li>
</ul>
<h2>¿Cómo filtrar una lista de listas en Python?</h2>
<p><strong>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 <code>[x for x in list if condition(x)]</code> y sustituye <code>condition(x)</code> por tu condición de filtrado que devuelva <code>True</code> para incluir la lista interna <code>x</code>, y <code>False</code> en caso contrario.</strong></p>
<p>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 <a href="https://blog.finxter.com/how-to-filter-a-list-in-python/">filtrar una lista</a>, y mucho menos una lista de listas en Python. ¡Este tutorial te muestra cómo hacer esto último!</p>
<p><strong>Problema</strong>: 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.</p>
<div class="wp-block-image">
<figure class="aligncenter size-large"><img src="https://blog.finxter.com/wp-content/uploads/2020/05/filter-scaled.jpg" alt=""/></figure>
</div>
<p><strong>Ejemplo</strong>: Dada la siguiente lista de listas con mediciones semanales de temperatura, y una lista interior semanal.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 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</pre>
<p>¿Cómo filtrar las semanas más frías con un valor medio de temperatura <8? Este es el resultado que deseas:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">print(cold_weeks)
# [[9, 9, 5, 6, 6, 9, 11], [10, 8, 8, 5, 6, 3, 1]]</pre>
<p>Hay dos métodos semánticamente equivalentes para lograr esto: la <a href="https://blog.finxter.com/list-comprehension/">comprensión de listas</a> y la <a href="https://blog.finxter.com/how-to-get-rid-of-pythons-map-function-with-list-comprehension/">función <code>map()</code></a>.</p>
<p><strong>Artículos Relacionados:</strong></p>
<ul>
<li><a href="https://blog.finxter.com/how-to-filter-a-list-of-lists-in-python/">¿Cómo filtrar una lista de listas en Python?</a></li>
<li><a href="https://blog.finxter.com/list-comprehension-python-list-of-lists/">Comprensión de listas — Lista de listas en Python</a></li>
<li><a href="https://blog.finxter.com/python-lists-filter-vs-list-comprehension-which-is-faster/">Filter() vs comprensión de lista</a></li>
<li><a href="https://blog.finxter.com/how-does-nested-list-comprehension-work-in-python/">Comprensión de lista anidada</a></li>
<li><a href="https://blog.finxter.com/python-lists/">La guía definitiva para las listas en Python</a></li>
<li><a href="https://blog.finxter.com/list-comprehension/">Comprensión de lista</a></li>
</ul>
<h2>Filtrar una lista de cadenas en Python</h2>
<p><strong>Problema</strong>: Dada una lista de cadenas y una cadena de búsqueda. ¿Cómo puedes filtrar las que contienen la cadena de búsqueda?</p>
<p><strong>Ejemplo</strong>: Digamos que tienes una lista <code>['Alice', 'Anne', 'Ann', 'Tom']</code> y quieres obtener todos los elementos que contienen la subcadena <code>'An'</code>. Esperas que la lista filtrada sea <code>['Anne', 'Ann']</code>.</p>
<p><strong>Solución</strong>: Utiliza el esquema de filtrado de comprensión de lista <code>[x for x in list if condition]</code> para descartar todos los elementos que no contengan otra cadena.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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']</pre>
<p>Utiliza la operación básica de pertenencia a la cadena “<code><a href="https://blog.finxter.com/python-membership-in-operator/" data-type="post" data-id="34005" target="_blank" rel="noreferrer noopener">in</a></code>” para comprobar si un elemento pasa el filtro o no.</p>
<h2>Filtrar una lista en Python para eliminar cadenas vacías</h2>
<p><strong>Problema</strong>: Dada una lista de cadenas. ¿Cómo puedes eliminar todas las cadenas vacías?</p>
<p><strong>Ejemplo</strong>: Digamos que tienes una lista <code>['Alice', 'Anne', '', 'Ann', '', 'Tom']</code> y quieres obtener una nueva lista <code>['Alice', 'Anne', 'Ann', 'Tom']</code> de cadenas no vacías.</p>
<p><strong>Solución</strong>: Utiliza el esquema de filtrado de comprensión de lista <code>[x for x in list if x]</code> para filtrar todas las cadenas vacías.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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']</pre>
<p>Aprovechas la característica de que Python asigna el valor booleano <code>False</code> a la cadena vacía <code>''</code>.</p>
<h2>Filtrar una lista en Python con endswith() y startswith()</h2>
<p><strong>Problema</strong>: 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.</p>
<p><strong>Ejemplo</strong>: Digamos que tienes una lista <code>['Alice', 'Anne', 'Ann', 'Tom']</code> y quieres obtener todos los elementos que empiezan por <code>'An'</code>. Esperas que la lista filtrada sea <code>['Anne', 'Ann']</code>.</p>
<p><strong>Solución</strong>: Utiliza el esquema de filtrado de comprensión de lista <code>[x for x in list if x.startswith('An')]</code> para filtrar todos los elementos que <a href="https://blog.finxter.com/regex-startswith-python/" target="_blank" rel="noreferrer noopener">empiezan por</a> <code>'An'</code>. Si deseas comprobar cadenas que terminan con otra cadena, puedes usar la función <code><a href="https://blog.finxter.com/regex-endswith-python/" target="_blank" rel="noreferrer noopener">str.endswith()</a></code> en su lugar.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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']</pre>
<p>Utiliza las funciones <code>startswith()</code> y <code>endswith()</code> como condiciones de filtrado.</p>
<h2>Filtrar una lista en Python con lambda</h2>
<p>La función <code>filter(function, iterable)</code> toma como argumento una función de filtrado que toma un elemento de la lista como entrada y devuelve el valor booleano <code>True</code> 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.</p>
<p>Para definir esta función, puedes utilizar la palabra clave lambda. La <a href="https://blog.finxter.com/how-to-filter-in-python-using-lambda-functions/" target="_blank" rel="noreferrer noopener">función lambda</a> 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.</p>
<p>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:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Create the list
lst = [1, 2, 3, 4] # Get all odd values
print(list(filter(lambda x: x%2, lst)))
# [1, 3]</pre>
<p>La función <code>lambda x: x%2</code> toma un argumento <code>x</code> -el elemento que hay que comprobar con el filtro- y devuelve el resultado de la expresión <code>x%2</code>. 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.</p>
<h2>Filtrar una lista en Python con otra lista</h2>
<p><strong>Problema</strong>: Dada una lista de valores <code>lst</code> y una lista de booleanos <code>filter</code>. ¿Cómo filtrar la primera lista usando la segunda lista? Más específicamente, quieres crear una nueva lista que incluya el <code>i</code>-ésimo elemento de <code>lst</code> si el <code>i</code>-ésimo elemento de filter es <code>True</code>.</p>
<p><strong>Ejemplo</strong>: Aquí hay dos listas de ejemplo:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">lst = [1, 2, 3, 4]
filter_lst = [True, False, False, True]</pre>
<p>Y deseas obtener esta lista:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[1, 4]</pre>
<p><strong>Solución</strong>: Utiliza una simple declaración de comprensión de lista <code>[lst[i] for i in range(len(lst)) if filter_lst[i]]</code> que compruebe para cada índice i si el valor booleano del filtro correspondiente es <code>True</code>. En este caso, se añade el elemento en el índice <code>i</code> en lst a la nueva lista filtrada. Este es el código:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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]</pre>
<p>La lista booleana sirve de “máscara” que determina qué elemento pasa el filtro y cuál no.</p>
<p>Una alternativa es usar la función <code>zip()</code> para iterar sobre múltiples secuencias sin necesidad de tocar ningún índice:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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]</pre>
<p>¿Necesitas mejorar tu comprensión de <code>zip()</code>? <a href="https://blog.finxter.com/zip-unzip-python/">¡Echa un vistazo a nuestro exhaustivo artículo del blog!</a></p>
<h2>Filtrar una lista en Python con índices</h2>
<p><strong>Problema</strong>: dada una lista de valores y una lista de índices. ¿Cómo filtrar todos los elementos con índices en la segunda lista?</p>
<p><strong>Ejemplo</strong>: Tienes la lista <code>['Alice', 'Bob', 'Ann', 'Frank']</code> y los índices <code>[1, 2]</code>. Lo que estás buscando es la lista filtrada <code>['Bob', 'Ann']</code>.</p>
<p><strong>Solución</strong>: 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 <code>[lst[i] for i in indices]</code>.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">lst = ['Alice', 'Bob', 'Ann', 'Frank']
indices = [1, 2] res = [lst[i] for i in indices]
print(res)
# ['Bob', 'Ann']</pre>
<p>Solo dos elementos con índices 1 y 2 pasan el filtro.</p>
<h2>Filtrar en Python una lista de diccionarios</h2>
<p><strong>Problema</strong>: 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 (<em>atributo</em>). ¿Cómo puedes lograrlo?</p>
<p><strong>Ejemplo minimalista</strong>: Considera el siguiente ejemplo en el que tienes tres diccionarios de usuarios con las claves username, <code>age</code> y <code>play_time</code>. Quieres obtener una lista de todos los usuarios que cumplen una determinada condición, como <code>play_time > 100</code>. Esto es lo que intentas conseguir:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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)</pre>
<p>El resultado debería parecerse a esto, donde el atributo play_time determina si un diccionario pasa el filtro o no, es decir, <code>play_time>100</code>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[{'username': 'alice', 'age': 23, 'play_time': 101},
{'username': 'ann', 'age': 25, 'play_time': 121}]</pre>
<p><strong>Solución</strong>: Utiliza la <a href="https://blog.finxter.com/how-to-get-rid-of-pythons-map-function-with-list-comprehension/" target="_blank" rel="noreferrer noopener">comprensión de lista</a> <code>[x for x in lst if condition(x)]</code> para crear una nueva lista de diccionarios que cumplan la condición. Todos los diccionarios en <code>lst</code> que no cumplen con la condición se filtran. Puedes definir tu propia condición sobre el elemento <code>x</code> de la lista.</p>
<p>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.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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)</pre>
<p>La salida es la lista filtrada de diccionarios que cumplen la condición:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[{'username': 'alice', 'age': 23, 'play_time': 101},
{'username': 'ann', 'age': 25, 'play_time': 121}]</pre>
<p><strong>Artículos relacionados en el blog de Finxter:</strong></p>
<ul>
<li><a href="https://blog.finxter.com/how-to-filter-a-list-of-dictionaries-in-python/">Cómo filtrar una lista de diccionarios</a></li>
<li><a href="https://blog.finxter.com/list-comprehension/">Comprensión de lista</a></li>
<li><a href="https://blog.finxter.com/a-simple-introduction-of-the-lambda-function-in-python/">Funciones Lambda</a></li>
<li><a href="https://blog.finxter.com/python-dictionary/">Diccionarios</a></li>
</ul>
<h2>Filtrar en Python elementos únicos en una lista – eliminar duplicados</h2>
<p><a href="https://blog.finxter.com/python-list-remove/">¿Cómo eliminar todos los duplicados de un valor dado en la lista?</a></p>
<p>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.</p>
<p>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.</p>
<p>Como valores del diccionario, simplemente tomas valores ficticios (por defecto).</p>
<p><strong>Artículos relacionados del blog:</strong></p>
<ul>
<li><a href="https://blog.finxter.com/python-dictionary/">¡Echa un vistazo a mi último tutorial de diccionario para un aprendizaje máximo!</a></li>
</ul>
<p>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.</p>
<p>Este es el código:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">>>> 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]</pre>
<h2>Filtrar en Python un rango en una lista</h2>
<p>Filtrar todos los elementos de una lista que estén dentro del rango de valores entre los índices de start y stop dados.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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]</pre>
<p>Empleas la condición <code>x>=start</code> y <code>x<=stop</code> para comprobar si la lista de elementos x está dentro del rango <code>[start, stop]</code> o no.</p>
<h2>Filtrar en Python una lista con mayor que y menor que</h2>
<p>Filtrar todos los elementos de una lista que sean mayores que un valor determinado y.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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]</pre>
<p>Utiliza la condición <code>x > y</code> para comprobar si el elemento de lista <code>x</code> es mayor que y o no. En el primer caso, se incluye en la lista filtrada. En el último, no.</p>
<p>Puedes utilizar la misma idea con el operador <a href="https://blog.finxter.com/python-less-than/" data-type="post" data-id="30841" target="_blank" rel="noreferrer noopener">menor que</a> <code><</code> mediante la declaración de comprensión de lista <code>[x for x in lst if x<y]</code>.</p>
<h2>Recuento de listas filtradas en Python</h2>
<p>¿Cómo puedes contar elementos bajo una determinada condición en <a href="https://blog.finxter.com/python-crash-course/">Python</a>? 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.</p>
<p>Digamos que tienes una condición para cada elemento <code>x</code>. Convirtámosla en una función con el nombre <code>condition(x)</code>. 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:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">def condition(x): return x > 10 print(condition(10))
# False print(condition(2))
# False print(condition(11))
# True</pre>
<p>Pero también puedes definir condiciones más complicadas, como comprobar si son números primos.</p>
<h3><strong>Recuento de listas en Python con if</strong></h3>
<p><strong>¿Cómo puedes contar los elementos de la lista SI se cumple la condición?</strong></p>
<p>La respuesta es utilizar una simple <a href="https://blog.finxter.com/python-one-line-for-loop-a-simple-tutorial/">expresión generadora</a> <code>sum(condition(x) for x in lst)</code>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">>>> def condition(x): return x>10 >>> lst = [10, 11, 42, 1, 2, 3]
>>> sum(condition(x) for x in lst)
2</pre>
<p>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.</p>
<h3><strong>Recuento de listas en Python con mayor / menor que</strong></h3>
<p>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:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">>>> def condition(x): return x>10 >>> lst = [10, 11, 42, 1, 2, 3]
>>> sum(condition(x) for x in lst)
2</pre>
<p>Por ejemplo, para encontrar el número de elementos menores que 5, usa la condición <code>x<5</code> en la expresión del generador:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">>>> lst = [10, 11, 42, 1, 2, 3]
>>> sum(x<5 for x in lst)
3</pre>
<h3><strong>Recuento de listas en Python de cero / no cero</strong></h3>
<p>Para contar el número de ceros en una lista dada, usa la llamada al método <code><a href="https://blog.finxter.com/python-list-count/" data-type="post" data-id="6984" target="_blank" rel="noreferrer noopener">list.count(0)</a></code>.</p>
<p>Para contar el número de no-ceros en una lista dada, debes utilizar el <em>recuento condicional</em>, tal y como se comentó anteriormente:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">def condition(x): return x!=0 lst = [10, 11, 42, 1, 2, 0, 0, 0]
print(sum(condition(x) for x in lst))
# 5</pre>
<h3><strong>Recuento de listas en Python con lambda + map</strong></h3>
<p>Una alternativa es utilizar una combinación de las funciones map y lambda.</p>
<p><strong>Artículos Relacionados:</strong></p>
<ul>
<li><a href="https://blog.finxter.com/how-to-get-rid-of-pythons-map-function-with-list-comprehension/">[Tutorial completo] Función map</a>: manipula cada elemento de un iterable.</li>
<li><a href="https://blog.finxter.com/a-simple-introduction-of-the-lambda-function-in-python/">[Tutorial completo] Función Lambda</a>: crea una función anónima.</li>
</ul>
<p>Este es el código:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">>>> sum(map(lambda x: x%2==0, [1, 2, 3, 4, 5]))
2</pre>
<p>Cuenta el número de enteros pares en la lista.</p>
<ul>
<li>La función lambda devuelve un valor booleano para un elemento dado <code>x</code>.</li>
<li>La función map transforma cada elemento de lista en un valor booleano (1 o 0).</li>
<li>La función sum suma los “1”.</li>
</ul>
<p>El resultado es el número de elementos para los que la condición se evalúa como True.</p>
<h2>Filtrar una lista por longitud de cadena en Python</h2>
<p>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?</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">coders = ['Ann', 'Alice', 'Frank', 'Pit']
filtered = [x for x in coders if len(x)>3]
print(filtered)
# ['Alice', 'Frank']</pre>
<p>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.</p>
<h2>Filtrar los elementos None de una lista en Python</h2>
<p>¿Cómo eliminar todos los valores None de una lista? Por ejemplo, tienes la lista <code>['Alice', None, 'Ann', None, None, 'Bob']</code> y quieres la lista <code>['Alice', 'Ann', 'Bob']</code>. ¿Cómo puedes lograrlo?</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">coders = ['Alice', None, 'Ann', None, None, 'Bob']
filtered = [x for x in coders if x]
print(filtered)
# ['Alice', 'Ann', 'Bob']</pre>
<p>En Python, cada elemento tiene un valor booleano asociado, por lo que puede usar cualquier objeto Python como condición. El valor <code>None</code> está asociado al valor booleano <code>False</code>.</p>
<h2>Filtrar en Python una lista JSON</h2>
<p><strong>Problema</strong>: Digamos que tienes un objeto de lista JSON. Quieres filtrar la lista en función de un atributo. ¿Cómo lograrlo?</p>
<p><strong>Ejemplo</strong>: Dada la siguiente lista JSON.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">json = [ { "user": "alice", "type": "free" }, { "user": "ann", "type": "paid" }, { "user": "bob", "type": "paid" }
]</pre>
<p>Quieres encontrar todos los usuarios que tienen un tipo de cuenta <code>'paid'</code>.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[ { "user": "ann", "type": "paid" }, { "user": "bob", "type": "paid" }
]</pre>
<p><strong>Solución</strong>: Utiliza la comprensión de lista <code>[x for x in json if x['type']=='paid']</code> para filtrar la lista y obtener una nueva lista json con los objetos que pasan el filtro.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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'}]</pre>
<p>Sólo Ann y Bob tienen una cuenta de pago y pasan el test <code>x['type']=='paid'</code>.</p>
<h2>Filtrar en una línea una lista en Python</h2>
<p><strong>¿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 <code>[x for x in list if condition]</code>, 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.</strong></p>
<p>Aquí hay un ejemplo:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">lst = ['Alice', 3, 5, 'Bob', 10] # ONE-LINER:
f = [x for x in lst if type(x)==str] print(f)
# ['Alice', 'Bob']</pre>
<p>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.</p>
<p>Si te gustan las sentencias de una sola línea, te encantará mi <a href="https://www.amazon.com/gp/product/B07ZY7XMX8">libro Python One-Liner (NoStarch Press 2020)</a>. Te muestra exactamente cómo escribir código pitónico y comprimir tu pensamiento y codificación a la forma más minimalista.</p>
<h2>Cómo filtrar una lista en Python de forma eficiente: filter() frente a comprensión de lista</h2>
<p><strong>[Spoiler] ¿Qué es más rápido para filtrar una lista: <code>filter()</code> 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 <code>filter()</code>.</strong></p>
<p>Para responder a esta <a href="https://blog.finxter.com/python-lists-filter-vs-list-comprehension-which-is-faster/" target="_blank" rel="noreferrer noopener">pregunta</a>, 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 <code>filter()</code> y de comprensión de lista.</p>
<p>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.</p>
<p>Utilicé mi portátil con un procesador Intel® Core i7-8565U a 1,8 GHz (con Turbo Boost hasta 4,6 GHz) y 8 GB de RAM.</p>
<p>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.</p>
<p>Este es el código que he utilizado para medir y representar los resultados: ¿qué método es más rápido: <code>filter()</code> o una comprensión de lista?</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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()</pre>
<p>El código compara los tiempos de ejecución de la función <code>filter()</code> y la variante de comprensión de lista para filtrar una lista. Ten en cuenta que la función <code>filter()</code> devuelve un objeto filter, por lo que debes convertirlo en lista mediante el constructor <code>list()</code>.</p>
<p>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.</p>
<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" width="640" height="480" src="https://blog.finxter.com/wp-content/uploads/2020/04/filter_list_comp.jpg" alt="" class="wp-image-7619" srcset="https://blog.finxter.com/wp-content/uploads/2020/04/filter_list_comp.jpg 640w, https://blog.finxter.com/wp-content/uplo...00x225.jpg 300w" sizes="(max-width: 640px) 100vw, 640px" /></figure>
</div>
<p>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 <code>time()</code> del <a href="https://docs.python.org/2/library/time.html#time.time">módulo time</a> no puede capturar el tiempo transcurrido.</p>
<p>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:</p>
<p><strong>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 <code>filter()</code>.</strong></p>
<p>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:</p>
<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" width="640" height="480" src="https://blog.finxter.com/wp-content/uploads/2020/04/filter_list_comp-1.jpg" alt="" class="wp-image-7620" srcset="https://blog.finxter.com/wp-content/uploads/2020/04/filter_list_comp-1.jpg 640w, https://blog.finxter.com/wp-content/uplo...00x225.jpg 300w" sizes="(max-width: 640px) 100vw, 640px" /></figure>
</div>
<p>De repente, la función <code>filter()</code> 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?</p>
<p>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 <code>next()</code>. Por lo tanto, la función <code>filter()</code> 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.</p>
<h2>A dónde ir desde aquí</h2>
<p><strong>Este tutorial te ha mostrado los entresijos de la función <code>filter()</code> en Python y la ha comparado con el método de comprensión de lista para filtrar: <code>[x for x in list if condition]</code>. 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!</strong></p>
<p>Si te encanta programar y quieres hacerlo a tiempo completo desde la comodidad de tu propia casa, estás de suerte:</p>
<p>He creado un <a href="https://blog.finxter.com/webinar-freelancer/">seminario web gratuito</a> 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.</p>
<p><a href="https://blog.finxter.com/webinar-freelancer/" target="_blank" rel="noreferrer noopener">Seminario web: ¿Cómo convertirse en un freelance de Python de seis cifras?</a></p>
<p>Únete a 21.419 codificadores ambiciosos de Python. Es divertido!</p>
</div>
https://www.sickgaming.net/blog/2022/04/...en-python/
<div><figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio">
<div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="¿Cómo filtrar una lista en Python?" width="780" height="439" src="https://www.youtube.com/embed/BoDmedffyuQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</figure>
<p>¿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 <a rel="noreferrer noopener" href="https://blog.finxter.com/list-comprehension/" data-type="post" data-id="1171" target="_blank">comprensión de lista</a> <code>[x for x in list if condition]</code> para filtrar todos los elementos de una lista. </p>
<h2>Filtrar con comprensión de lista</h2>
<p>La forma más pitónica de filtrar una lista, en mi opinión, es la declaración de comprensión de lista <code>[x for x in list if condition]</code>. Puedes sustituir la condición por cualquier función de <code>x</code> que quieras utilizar como condición de filtrado.</p>
<p>Por ejemplo, si quieres filtrar todos los elementos menores de, digamos, 10, utilizarías la declaración de comprensión de lista <code>[x for x in list if x<10]</code> para crear una nueva lista con todos los elementos de la lista menores de 10.</p>
<p>Aquí hay tres ejemplos de filtrado de una lista:</p>
<ul>
<li>Obtener elementos menores de ocho: <code>[x for x in lst if x<8]</code>.</li>
<li>Obtener elementos pares: <code>[x for x in lst if x%2==0]</code>.</li>
<li>Obtener elementos impares: <code>[x for x in lst if x%2]</code>.</li>
</ul>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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)</pre>
<p>El resultado es:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Elements <8
[2, 6, 4, 3, 1] # Even Elements
[8, 2, 6, 4] # Odd Elements
[3, 1]</pre>
<p>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.</p>
<h2>Filtrar una lista en Python con filter()</h2>
<p>La función <code>filter(function, iterable)</code> 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 <code><a href="https://blog.finxter.com/iterators-iterables-and-itertools/" data-type="post" data-id="29507" target="_blank" rel="noreferrer noopener">iterable</a></code> (un objeto filter).</p>
<p>Puedes emplear una declaración de función <code>lambda</code> 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 <a href="https://blog.finxter.com/a-simple-introduction-of-the-lambda-function-in-python/">artículo detallado del blog sobre la función lambda</a>.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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))</pre>
<p>El resultado es:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Elements <8
[2, 6, 4, 3, 1] # Even Elements
[8, 2, 6, 4] # Odd Elements
[3, 1]</pre>
<p>La función <code>filter()</code> devuelve un objeto filter que es iterable. Para convertirlo en una lista, se utiliza el constructor <code><a href="https://blog.finxter.com/python-list/" data-type="post" data-id="21502" target="_blank" rel="noreferrer noopener">list(...)</a></code>.</p>
<p><strong>Artículo relacionado:</strong></p>
<ul>
<li><a href="https://blog.finxter.com/how-to-filter-in-python-using-lambda-functions/">Cómo filtrar usando la función lambda</a></li>
</ul>
<h2>Filtrar una lista en Python con map()</h2>
<p>Sólo añado esta opción porque hay gente que aún intenta utilizar la función <code>map()</code> para filtrar elementos de una lista. Está claro que esta es la forma incorrecta de hacerlo. La razón es que la función <code><a href="https://blog.finxter.com/daily-python-puzzle-string-encrpytion-ord-function-map-function/" target="_blank" rel="noreferrer noopener">map()</a></code> 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 <a href="https://blog.finxter.com/list-to-dict-convert-a-list-into-a-dictionary-in-python/" target="_blank" rel="noreferrer noopener">comprensión de lista</a>). 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.</p>
<p>A esto me refiero:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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)</pre>
<p>El resultado vuelve a ser el mismo:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[2, 6, 4, 3, 1]
[8, 2, 6, 4]
[3, 1]</pre>
<p>Pero el método para obtener este resultado es claramente ineficaz y no resulta legible.</p>
<p><strong>Artículos Relacionados:</strong></p>
<ul>
<li><a href="https://blog.finxter.com/how-to-get-rid-of-pythons-map-function-with-list-comprehension/">Cómo deshacerse de la función <code>map()</code> (y por qué Guido la odiaba)</a></li>
</ul>
<h2>Filtrar una lista en Python con generador</h2>
<p>Una <a href="https://blog.finxter.com/how-to-use-generator-expressions-in-python-dictionaries/">expresión generadora</a> 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.</p>
<p>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.</p>
<ul>
<li>Primero, determina el iterable de valores que cumplen una determinada condición.</li>
<li>En segundo lugar, suma todos esos valores con la función <code><a href="https://blog.finxter.com/python-sum/" data-type="post" data-id="22221" target="_blank" rel="noreferrer noopener">sum()</a></code>.</li>
</ul>
<p>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:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">lst = [6, 8, 2, 8, 'Alice']
print(sum(x for x in lst if type(x) == int))
# 24</pre>
<p>Comprueba el <code><a href="https://blog.finxter.com/python-type/" data-type="post" data-id="23967" target="_blank" rel="noreferrer noopener">type(x)</a></code> de cada elemento y compáralo con el tipo integer. Esta comparación devuelve True si el elemento es, de hecho, de tipo entero.</p>
<h2>Filtrar una lista en Python con condición</h2>
<p>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, <code>condition(x)</code>) que tome un elemento de la lista como entrada y devuelva el valor booleano <code>True</code> si se cumple la condición o <code>False</code> en caso contrario.</p>
<p>Aquí tienes un ejemplo de código:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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]</pre>
<p>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.</p>
<h2>Filtrar una lista en Python con condiciones múltiples</h2>
<p>Lo mismo se aplica si quieres combinar varias condiciones. Digamos que deseas filtrar todos los elementos <code>x>9</code> y <code>x<1</code>. 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, <code>condition(x)</code>) 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.</p>
<p>Aquí está el mismo ejemplo de código que antes:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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]</pre>
<p>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.</p>
<h2>Filtrar una lista en Python con Regex</h2>
<p><strong>Problema</strong>: Dada una lista de cadenas. ¿Cómo puedes filtrar aquellas que coincidan con una determinada <a href="https://blog.finxter.com/python-regex/">expresión regular</a>?</p>
<p><strong>Ejemplo</strong>: Digamos que tienes una lista <code>['Alice', 'Anne', 'Ann', 'Tom']</code> y quieres descartar los elementos que no cumplen el patrón regex <code>'A.*e'</code>. Esperas que la lista filtrada sea <code>['Alice', 'Anne']</code>.</p>
<p><strong>Solución</strong>: Utiliza el marco de filtrado de comprensión de lista <code>[x for x in list if match]</code> para filtrar todos los elementos que no concuerden con una cadena determinada.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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']</pre>
<p>Utiliza el método <code>re.match()</code> 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, <code>None</code>, 0, 0.0, etc.). Si necesitas refrescar tus conocimientos básicos sobre la función <code>re.match()</code>, echa un vistazo a mi detallado <a href="https://blog.finxter.com/python-regex-match/">artículo del blog</a> que te lleva paso a paso por esta potente herramienta de Python.</p>
<p><strong>Artículos Relacionados:</strong></p>
<ul>
<li><a href="https://blog.finxter.com/python-how-to-count-elements-in-a-list-matching-a-condition/">Cómo contar elementos de una lista que coincidan con una condición</a></li>
<li><a href="https://blog.finxter.com/how-to-match-an-exact-word-in-python-regex-answer-dont/">Cómo hacer coincidir una palabra exacta en Python</a></li>
<li><a href="https://blog.finxter.com/python-regex-how-to-count-the-number-of-matches/">Cómo contar el número de coincidencias en Python</a></li>
</ul>
<h2>¿Cómo filtrar una lista de listas en Python?</h2>
<p><strong>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 <code>[x for x in list if condition(x)]</code> y sustituye <code>condition(x)</code> por tu condición de filtrado que devuelva <code>True</code> para incluir la lista interna <code>x</code>, y <code>False</code> en caso contrario.</strong></p>
<p>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 <a href="https://blog.finxter.com/how-to-filter-a-list-in-python/">filtrar una lista</a>, y mucho menos una lista de listas en Python. ¡Este tutorial te muestra cómo hacer esto último!</p>
<p><strong>Problema</strong>: 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.</p>
<div class="wp-block-image">
<figure class="aligncenter size-large"><img src="https://blog.finxter.com/wp-content/uploads/2020/05/filter-scaled.jpg" alt=""/></figure>
</div>
<p><strong>Ejemplo</strong>: Dada la siguiente lista de listas con mediciones semanales de temperatura, y una lista interior semanal.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 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</pre>
<p>¿Cómo filtrar las semanas más frías con un valor medio de temperatura <8? Este es el resultado que deseas:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">print(cold_weeks)
# [[9, 9, 5, 6, 6, 9, 11], [10, 8, 8, 5, 6, 3, 1]]</pre>
<p>Hay dos métodos semánticamente equivalentes para lograr esto: la <a href="https://blog.finxter.com/list-comprehension/">comprensión de listas</a> y la <a href="https://blog.finxter.com/how-to-get-rid-of-pythons-map-function-with-list-comprehension/">función <code>map()</code></a>.</p>
<p><strong>Artículos Relacionados:</strong></p>
<ul>
<li><a href="https://blog.finxter.com/how-to-filter-a-list-of-lists-in-python/">¿Cómo filtrar una lista de listas en Python?</a></li>
<li><a href="https://blog.finxter.com/list-comprehension-python-list-of-lists/">Comprensión de listas — Lista de listas en Python</a></li>
<li><a href="https://blog.finxter.com/python-lists-filter-vs-list-comprehension-which-is-faster/">Filter() vs comprensión de lista</a></li>
<li><a href="https://blog.finxter.com/how-does-nested-list-comprehension-work-in-python/">Comprensión de lista anidada</a></li>
<li><a href="https://blog.finxter.com/python-lists/">La guía definitiva para las listas en Python</a></li>
<li><a href="https://blog.finxter.com/list-comprehension/">Comprensión de lista</a></li>
</ul>
<h2>Filtrar una lista de cadenas en Python</h2>
<p><strong>Problema</strong>: Dada una lista de cadenas y una cadena de búsqueda. ¿Cómo puedes filtrar las que contienen la cadena de búsqueda?</p>
<p><strong>Ejemplo</strong>: Digamos que tienes una lista <code>['Alice', 'Anne', 'Ann', 'Tom']</code> y quieres obtener todos los elementos que contienen la subcadena <code>'An'</code>. Esperas que la lista filtrada sea <code>['Anne', 'Ann']</code>.</p>
<p><strong>Solución</strong>: Utiliza el esquema de filtrado de comprensión de lista <code>[x for x in list if condition]</code> para descartar todos los elementos que no contengan otra cadena.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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']</pre>
<p>Utiliza la operación básica de pertenencia a la cadena “<code><a href="https://blog.finxter.com/python-membership-in-operator/" data-type="post" data-id="34005" target="_blank" rel="noreferrer noopener">in</a></code>” para comprobar si un elemento pasa el filtro o no.</p>
<h2>Filtrar una lista en Python para eliminar cadenas vacías</h2>
<p><strong>Problema</strong>: Dada una lista de cadenas. ¿Cómo puedes eliminar todas las cadenas vacías?</p>
<p><strong>Ejemplo</strong>: Digamos que tienes una lista <code>['Alice', 'Anne', '', 'Ann', '', 'Tom']</code> y quieres obtener una nueva lista <code>['Alice', 'Anne', 'Ann', 'Tom']</code> de cadenas no vacías.</p>
<p><strong>Solución</strong>: Utiliza el esquema de filtrado de comprensión de lista <code>[x for x in list if x]</code> para filtrar todas las cadenas vacías.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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']</pre>
<p>Aprovechas la característica de que Python asigna el valor booleano <code>False</code> a la cadena vacía <code>''</code>.</p>
<h2>Filtrar una lista en Python con endswith() y startswith()</h2>
<p><strong>Problema</strong>: 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.</p>
<p><strong>Ejemplo</strong>: Digamos que tienes una lista <code>['Alice', 'Anne', 'Ann', 'Tom']</code> y quieres obtener todos los elementos que empiezan por <code>'An'</code>. Esperas que la lista filtrada sea <code>['Anne', 'Ann']</code>.</p>
<p><strong>Solución</strong>: Utiliza el esquema de filtrado de comprensión de lista <code>[x for x in list if x.startswith('An')]</code> para filtrar todos los elementos que <a href="https://blog.finxter.com/regex-startswith-python/" target="_blank" rel="noreferrer noopener">empiezan por</a> <code>'An'</code>. Si deseas comprobar cadenas que terminan con otra cadena, puedes usar la función <code><a href="https://blog.finxter.com/regex-endswith-python/" target="_blank" rel="noreferrer noopener">str.endswith()</a></code> en su lugar.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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']</pre>
<p>Utiliza las funciones <code>startswith()</code> y <code>endswith()</code> como condiciones de filtrado.</p>
<h2>Filtrar una lista en Python con lambda</h2>
<p>La función <code>filter(function, iterable)</code> toma como argumento una función de filtrado que toma un elemento de la lista como entrada y devuelve el valor booleano <code>True</code> 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.</p>
<p>Para definir esta función, puedes utilizar la palabra clave lambda. La <a href="https://blog.finxter.com/how-to-filter-in-python-using-lambda-functions/" target="_blank" rel="noreferrer noopener">función lambda</a> 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.</p>
<p>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:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Create the list
lst = [1, 2, 3, 4] # Get all odd values
print(list(filter(lambda x: x%2, lst)))
# [1, 3]</pre>
<p>La función <code>lambda x: x%2</code> toma un argumento <code>x</code> -el elemento que hay que comprobar con el filtro- y devuelve el resultado de la expresión <code>x%2</code>. 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.</p>
<h2>Filtrar una lista en Python con otra lista</h2>
<p><strong>Problema</strong>: Dada una lista de valores <code>lst</code> y una lista de booleanos <code>filter</code>. ¿Cómo filtrar la primera lista usando la segunda lista? Más específicamente, quieres crear una nueva lista que incluya el <code>i</code>-ésimo elemento de <code>lst</code> si el <code>i</code>-ésimo elemento de filter es <code>True</code>.</p>
<p><strong>Ejemplo</strong>: Aquí hay dos listas de ejemplo:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">lst = [1, 2, 3, 4]
filter_lst = [True, False, False, True]</pre>
<p>Y deseas obtener esta lista:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[1, 4]</pre>
<p><strong>Solución</strong>: Utiliza una simple declaración de comprensión de lista <code>[lst[i] for i in range(len(lst)) if filter_lst[i]]</code> que compruebe para cada índice i si el valor booleano del filtro correspondiente es <code>True</code>. En este caso, se añade el elemento en el índice <code>i</code> en lst a la nueva lista filtrada. Este es el código:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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]</pre>
<p>La lista booleana sirve de “máscara” que determina qué elemento pasa el filtro y cuál no.</p>
<p>Una alternativa es usar la función <code>zip()</code> para iterar sobre múltiples secuencias sin necesidad de tocar ningún índice:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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]</pre>
<p>¿Necesitas mejorar tu comprensión de <code>zip()</code>? <a href="https://blog.finxter.com/zip-unzip-python/">¡Echa un vistazo a nuestro exhaustivo artículo del blog!</a></p>
<h2>Filtrar una lista en Python con índices</h2>
<p><strong>Problema</strong>: dada una lista de valores y una lista de índices. ¿Cómo filtrar todos los elementos con índices en la segunda lista?</p>
<p><strong>Ejemplo</strong>: Tienes la lista <code>['Alice', 'Bob', 'Ann', 'Frank']</code> y los índices <code>[1, 2]</code>. Lo que estás buscando es la lista filtrada <code>['Bob', 'Ann']</code>.</p>
<p><strong>Solución</strong>: 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 <code>[lst[i] for i in indices]</code>.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">lst = ['Alice', 'Bob', 'Ann', 'Frank']
indices = [1, 2] res = [lst[i] for i in indices]
print(res)
# ['Bob', 'Ann']</pre>
<p>Solo dos elementos con índices 1 y 2 pasan el filtro.</p>
<h2>Filtrar en Python una lista de diccionarios</h2>
<p><strong>Problema</strong>: 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 (<em>atributo</em>). ¿Cómo puedes lograrlo?</p>
<p><strong>Ejemplo minimalista</strong>: Considera el siguiente ejemplo en el que tienes tres diccionarios de usuarios con las claves username, <code>age</code> y <code>play_time</code>. Quieres obtener una lista de todos los usuarios que cumplen una determinada condición, como <code>play_time > 100</code>. Esto es lo que intentas conseguir:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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)</pre>
<p>El resultado debería parecerse a esto, donde el atributo play_time determina si un diccionario pasa el filtro o no, es decir, <code>play_time>100</code>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[{'username': 'alice', 'age': 23, 'play_time': 101},
{'username': 'ann', 'age': 25, 'play_time': 121}]</pre>
<p><strong>Solución</strong>: Utiliza la <a href="https://blog.finxter.com/how-to-get-rid-of-pythons-map-function-with-list-comprehension/" target="_blank" rel="noreferrer noopener">comprensión de lista</a> <code>[x for x in lst if condition(x)]</code> para crear una nueva lista de diccionarios que cumplan la condición. Todos los diccionarios en <code>lst</code> que no cumplen con la condición se filtran. Puedes definir tu propia condición sobre el elemento <code>x</code> de la lista.</p>
<p>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.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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)</pre>
<p>La salida es la lista filtrada de diccionarios que cumplen la condición:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[{'username': 'alice', 'age': 23, 'play_time': 101},
{'username': 'ann', 'age': 25, 'play_time': 121}]</pre>
<p><strong>Artículos relacionados en el blog de Finxter:</strong></p>
<ul>
<li><a href="https://blog.finxter.com/how-to-filter-a-list-of-dictionaries-in-python/">Cómo filtrar una lista de diccionarios</a></li>
<li><a href="https://blog.finxter.com/list-comprehension/">Comprensión de lista</a></li>
<li><a href="https://blog.finxter.com/a-simple-introduction-of-the-lambda-function-in-python/">Funciones Lambda</a></li>
<li><a href="https://blog.finxter.com/python-dictionary/">Diccionarios</a></li>
</ul>
<h2>Filtrar en Python elementos únicos en una lista – eliminar duplicados</h2>
<p><a href="https://blog.finxter.com/python-list-remove/">¿Cómo eliminar todos los duplicados de un valor dado en la lista?</a></p>
<p>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.</p>
<p>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.</p>
<p>Como valores del diccionario, simplemente tomas valores ficticios (por defecto).</p>
<p><strong>Artículos relacionados del blog:</strong></p>
<ul>
<li><a href="https://blog.finxter.com/python-dictionary/">¡Echa un vistazo a mi último tutorial de diccionario para un aprendizaje máximo!</a></li>
</ul>
<p>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.</p>
<p>Este es el código:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">>>> 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]</pre>
<h2>Filtrar en Python un rango en una lista</h2>
<p>Filtrar todos los elementos de una lista que estén dentro del rango de valores entre los índices de start y stop dados.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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]</pre>
<p>Empleas la condición <code>x>=start</code> y <code>x<=stop</code> para comprobar si la lista de elementos x está dentro del rango <code>[start, stop]</code> o no.</p>
<h2>Filtrar en Python una lista con mayor que y menor que</h2>
<p>Filtrar todos los elementos de una lista que sean mayores que un valor determinado y.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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]</pre>
<p>Utiliza la condición <code>x > y</code> para comprobar si el elemento de lista <code>x</code> es mayor que y o no. En el primer caso, se incluye en la lista filtrada. En el último, no.</p>
<p>Puedes utilizar la misma idea con el operador <a href="https://blog.finxter.com/python-less-than/" data-type="post" data-id="30841" target="_blank" rel="noreferrer noopener">menor que</a> <code><</code> mediante la declaración de comprensión de lista <code>[x for x in lst if x<y]</code>.</p>
<h2>Recuento de listas filtradas en Python</h2>
<p>¿Cómo puedes contar elementos bajo una determinada condición en <a href="https://blog.finxter.com/python-crash-course/">Python</a>? 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.</p>
<p>Digamos que tienes una condición para cada elemento <code>x</code>. Convirtámosla en una función con el nombre <code>condition(x)</code>. 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:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">def condition(x): return x > 10 print(condition(10))
# False print(condition(2))
# False print(condition(11))
# True</pre>
<p>Pero también puedes definir condiciones más complicadas, como comprobar si son números primos.</p>
<h3><strong>Recuento de listas en Python con if</strong></h3>
<p><strong>¿Cómo puedes contar los elementos de la lista SI se cumple la condición?</strong></p>
<p>La respuesta es utilizar una simple <a href="https://blog.finxter.com/python-one-line-for-loop-a-simple-tutorial/">expresión generadora</a> <code>sum(condition(x) for x in lst)</code>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">>>> def condition(x): return x>10 >>> lst = [10, 11, 42, 1, 2, 3]
>>> sum(condition(x) for x in lst)
2</pre>
<p>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.</p>
<h3><strong>Recuento de listas en Python con mayor / menor que</strong></h3>
<p>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:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">>>> def condition(x): return x>10 >>> lst = [10, 11, 42, 1, 2, 3]
>>> sum(condition(x) for x in lst)
2</pre>
<p>Por ejemplo, para encontrar el número de elementos menores que 5, usa la condición <code>x<5</code> en la expresión del generador:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">>>> lst = [10, 11, 42, 1, 2, 3]
>>> sum(x<5 for x in lst)
3</pre>
<h3><strong>Recuento de listas en Python de cero / no cero</strong></h3>
<p>Para contar el número de ceros en una lista dada, usa la llamada al método <code><a href="https://blog.finxter.com/python-list-count/" data-type="post" data-id="6984" target="_blank" rel="noreferrer noopener">list.count(0)</a></code>.</p>
<p>Para contar el número de no-ceros en una lista dada, debes utilizar el <em>recuento condicional</em>, tal y como se comentó anteriormente:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">def condition(x): return x!=0 lst = [10, 11, 42, 1, 2, 0, 0, 0]
print(sum(condition(x) for x in lst))
# 5</pre>
<h3><strong>Recuento de listas en Python con lambda + map</strong></h3>
<p>Una alternativa es utilizar una combinación de las funciones map y lambda.</p>
<p><strong>Artículos Relacionados:</strong></p>
<ul>
<li><a href="https://blog.finxter.com/how-to-get-rid-of-pythons-map-function-with-list-comprehension/">[Tutorial completo] Función map</a>: manipula cada elemento de un iterable.</li>
<li><a href="https://blog.finxter.com/a-simple-introduction-of-the-lambda-function-in-python/">[Tutorial completo] Función Lambda</a>: crea una función anónima.</li>
</ul>
<p>Este es el código:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">>>> sum(map(lambda x: x%2==0, [1, 2, 3, 4, 5]))
2</pre>
<p>Cuenta el número de enteros pares en la lista.</p>
<ul>
<li>La función lambda devuelve un valor booleano para un elemento dado <code>x</code>.</li>
<li>La función map transforma cada elemento de lista en un valor booleano (1 o 0).</li>
<li>La función sum suma los “1”.</li>
</ul>
<p>El resultado es el número de elementos para los que la condición se evalúa como True.</p>
<h2>Filtrar una lista por longitud de cadena en Python</h2>
<p>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?</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">coders = ['Ann', 'Alice', 'Frank', 'Pit']
filtered = [x for x in coders if len(x)>3]
print(filtered)
# ['Alice', 'Frank']</pre>
<p>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.</p>
<h2>Filtrar los elementos None de una lista en Python</h2>
<p>¿Cómo eliminar todos los valores None de una lista? Por ejemplo, tienes la lista <code>['Alice', None, 'Ann', None, None, 'Bob']</code> y quieres la lista <code>['Alice', 'Ann', 'Bob']</code>. ¿Cómo puedes lograrlo?</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">coders = ['Alice', None, 'Ann', None, None, 'Bob']
filtered = [x for x in coders if x]
print(filtered)
# ['Alice', 'Ann', 'Bob']</pre>
<p>En Python, cada elemento tiene un valor booleano asociado, por lo que puede usar cualquier objeto Python como condición. El valor <code>None</code> está asociado al valor booleano <code>False</code>.</p>
<h2>Filtrar en Python una lista JSON</h2>
<p><strong>Problema</strong>: Digamos que tienes un objeto de lista JSON. Quieres filtrar la lista en función de un atributo. ¿Cómo lograrlo?</p>
<p><strong>Ejemplo</strong>: Dada la siguiente lista JSON.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">json = [ { "user": "alice", "type": "free" }, { "user": "ann", "type": "paid" }, { "user": "bob", "type": "paid" }
]</pre>
<p>Quieres encontrar todos los usuarios que tienen un tipo de cuenta <code>'paid'</code>.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[ { "user": "ann", "type": "paid" }, { "user": "bob", "type": "paid" }
]</pre>
<p><strong>Solución</strong>: Utiliza la comprensión de lista <code>[x for x in json if x['type']=='paid']</code> para filtrar la lista y obtener una nueva lista json con los objetos que pasan el filtro.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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'}]</pre>
<p>Sólo Ann y Bob tienen una cuenta de pago y pasan el test <code>x['type']=='paid'</code>.</p>
<h2>Filtrar en una línea una lista en Python</h2>
<p><strong>¿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 <code>[x for x in list if condition]</code>, 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.</strong></p>
<p>Aquí hay un ejemplo:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">lst = ['Alice', 3, 5, 'Bob', 10] # ONE-LINER:
f = [x for x in lst if type(x)==str] print(f)
# ['Alice', 'Bob']</pre>
<p>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.</p>
<p>Si te gustan las sentencias de una sola línea, te encantará mi <a href="https://www.amazon.com/gp/product/B07ZY7XMX8">libro Python One-Liner (NoStarch Press 2020)</a>. Te muestra exactamente cómo escribir código pitónico y comprimir tu pensamiento y codificación a la forma más minimalista.</p>
<h2>Cómo filtrar una lista en Python de forma eficiente: filter() frente a comprensión de lista</h2>
<p><strong>[Spoiler] ¿Qué es más rápido para filtrar una lista: <code>filter()</code> 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 <code>filter()</code>.</strong></p>
<p>Para responder a esta <a href="https://blog.finxter.com/python-lists-filter-vs-list-comprehension-which-is-faster/" target="_blank" rel="noreferrer noopener">pregunta</a>, 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 <code>filter()</code> y de comprensión de lista.</p>
<p>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.</p>
<p>Utilicé mi portátil con un procesador Intel® Core i7-8565U a 1,8 GHz (con Turbo Boost hasta 4,6 GHz) y 8 GB de RAM.</p>
<p>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.</p>
<p>Este es el código que he utilizado para medir y representar los resultados: ¿qué método es más rápido: <code>filter()</code> o una comprensión de lista?</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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()</pre>
<p>El código compara los tiempos de ejecución de la función <code>filter()</code> y la variante de comprensión de lista para filtrar una lista. Ten en cuenta que la función <code>filter()</code> devuelve un objeto filter, por lo que debes convertirlo en lista mediante el constructor <code>list()</code>.</p>
<p>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.</p>
<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" width="640" height="480" src="https://blog.finxter.com/wp-content/uploads/2020/04/filter_list_comp.jpg" alt="" class="wp-image-7619" srcset="https://blog.finxter.com/wp-content/uploads/2020/04/filter_list_comp.jpg 640w, https://blog.finxter.com/wp-content/uplo...00x225.jpg 300w" sizes="(max-width: 640px) 100vw, 640px" /></figure>
</div>
<p>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 <code>time()</code> del <a href="https://docs.python.org/2/library/time.html#time.time">módulo time</a> no puede capturar el tiempo transcurrido.</p>
<p>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:</p>
<p><strong>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 <code>filter()</code>.</strong></p>
<p>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:</p>
<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" width="640" height="480" src="https://blog.finxter.com/wp-content/uploads/2020/04/filter_list_comp-1.jpg" alt="" class="wp-image-7620" srcset="https://blog.finxter.com/wp-content/uploads/2020/04/filter_list_comp-1.jpg 640w, https://blog.finxter.com/wp-content/uplo...00x225.jpg 300w" sizes="(max-width: 640px) 100vw, 640px" /></figure>
</div>
<p>De repente, la función <code>filter()</code> 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?</p>
<p>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 <code>next()</code>. Por lo tanto, la función <code>filter()</code> 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.</p>
<h2>A dónde ir desde aquí</h2>
<p><strong>Este tutorial te ha mostrado los entresijos de la función <code>filter()</code> en Python y la ha comparado con el método de comprensión de lista para filtrar: <code>[x for x in list if condition]</code>. 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!</strong></p>
<p>Si te encanta programar y quieres hacerlo a tiempo completo desde la comodidad de tu propia casa, estás de suerte:</p>
<p>He creado un <a href="https://blog.finxter.com/webinar-freelancer/">seminario web gratuito</a> 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.</p>
<p><a href="https://blog.finxter.com/webinar-freelancer/" target="_blank" rel="noreferrer noopener">Seminario web: ¿Cómo convertirse en un freelance de Python de seis cifras?</a></p>
<p>Únete a 21.419 codificadores ambiciosos de Python. Es divertido!</p>
</div>
https://www.sickgaming.net/blog/2022/04/...en-python/