Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

172
Vistas
Filtre todo antes de que se cumpla una condición, mantenga todos los elementos después

Me preguntaba si había una solución fácil para el siguiente problema. El problema aquí es que quiero mantener todos los elementos que aparecen dentro de esta lista después de que la condición inicial sea verdadera. La condición aquí es que quiero eliminar todo antes de que la condición de que un valor sea mayor que 18 sea verdadera, pero conservar todo después. Ejemplo

Aporte:

 p = [4,9,10,4,20,13,29,3,39]

Rendimiento esperado:

 p = [20,13,29,3,39]

Sé que puedes filtrar toda la lista a través de

 [x for x in p if x>18]

Pero quiero detener esta operación una vez que se encuentra el primer valor por encima de 18, y luego incluir el resto de los valores independientemente de si cumplen la condición o no. Parece un problema fácil, pero aún no he encontrado la solución.

over 4 years ago · Santiago Trujillo
5 Respuestas
Responde la pregunta

0

En mi experiencia, al menos para las listas de enteros, usar enumerate solo para encontrar un índice y descartar todos los demás índices es un desperdicio que es más rápido encontrar primero solo el elemento y luego usar list.index para encontrar su índice. Basado en algunas pruebas, espero que sea un factor 1.44 más rápido que la solución explicit_loop (que usa enumerate ) en el punto de referencia de @enke .

 def start_over_18(p): for x in p: if x > 18: return p[p.index(x):] return []

Otra solución, usar un iterador para no tener que preocuparme por los índices. Parece ser el doble de rápido que la solución explicit_loop :

 def start_over_18(p): it = iter(p) for x in it: if x > 18: return [x, *it] return []
over 4 years ago · Santiago Trujillo Denunciar

0

Puedes usar itertools.dropwhile :

 from itertools import dropwhile p = [4,9,10,4,20,13,29,3,39] p = dropwhile(lambda x: x <= 18, p) print(*p) # 20 13 29 3 39

En mi opinión, esta es posiblemente la versión más fácil de leer. Esto también corresponde a un patrón común en otros lenguajes de programación funcionales, como dropWhile (<=18) p en Haskell y p.dropWhile(_ <= 18) en Scala.


Alternativamente, usando el operador morsa (solo disponible en python 3.8+):

 exceeded = False p = [x for x in p if (exceeded := exceeded or x > 18)] print(p) # [20, 13, 29, 3, 39]

Pero supongo que a algunas personas no les gusta este estilo. En ese caso, se puede hacer un bucle for explícito (sugerencia de ilkkachu):

 for i, x in enumerate(p): if x > 18: output = p[i:] break else: output = [] # alternatively just put output = [] before for
over 4 years ago · Santiago Trujillo Denunciar

0

Excelentes soluciones aquí, solo quería demostrar cómo hacerlo con numpy:

 >>> import numpy as np >>> p[(np.array(p) > 18).argmax():] [20, 13, 29, 3, 39]

Como hay muchas buenas respuestas aquí, decidí ejecutar algunos puntos de referencia simples. El primero usa la matriz de muestra del OP ( [4,9,10,4,20,13,29,3,39] ) de longitud 9. El segundo usa una matriz generada aleatoriamente de longitud 20 mil, donde la primera mitad está entre 0 y 15, y la segunda mitad está entre -20 y 30 (para que la división no ocurra justo en el centro).

Usando los datos del OP (matriz de longitud 9):

 %timeit enke() 650 ns ± 15.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) %timeit j1lee1() 546 ns ± 4.22 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) %timeit j1lee2() 551 ns ± 19 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) %timeit j2lee3() 536 ns ± 12.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) %timeit richardec() 2.08 µs ± 16 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Usando una matriz de longitud 20,000 (20 mil):

 %timeit enke() 1.5 ms ± 34.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) %timeit j1lee1() 1.95 ms ± 43 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) %timeit j1lee2() 2.1 ms ± 53.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) %timeit j2lee3() 2.33 ms ± 96.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) %timeit richardec() 13.3 µs ± 461 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Código para generar la segunda matriz:

 p = np.hstack([np.random.randint(0,15,10000),np.random.randint(-20,30,10000)])

Entonces, para el caso pequeño, numpy es una babosa y no es necesario. ¡Pero el caso grande, numpy es casi 100 veces más rápido y el camino a seguir! :)

over 4 years ago · Santiago Trujillo Denunciar

0

Me di cuenta de que el OP menciona en una respuesta que p es en realidad un Pandas DataFrame. Aquí hay un método para filtrar todos los elementos hasta la primera instancia de un número mayor a 18 usando Pandas:

 import pandas as pd df = pd.DataFrame([4,9,10,4,20,13,29,3,39]) df = df[df[0].gt(18).idxmax():] print(df)

Salidas:

 0 4 20 5 13 6 29 7 3 8 39

Nota: estoy ciego a la estructura real de su DataFrame, así que solo usé exactamente lo que se me dio.

over 4 years ago · Santiago Trujillo Denunciar

0

no debería break suficiente?

algo como:

 import numpy as np input= np.array([4,9,10,4,20,13,29,3,39]) for index, item in enumerate(input): if(item>=18): print(input[index:]) break

más información en:

https://www.poftut.com/control-python-loop-break-statement/#:~:text=Python%20provides%20for%20loops%20in,según%20to%20the%20current%20condition .

https://problemsolutionwithpython.com/05-NumPy-and-Arrays/05.06-Array-Slicing/

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda