Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

193
Views
¿Por qué any (True for... if cond) es mucho más rápido que any (cond for...)?

Dos formas similares de verificar si una lista contiene un número impar:

 any(x % 2 for x in a) any(True for x in a if x % 2)

Resultados de tiempo con a = [0] * 10000000 (cinco intentos cada uno, tiempos en segundos):

 0.60 0.60 0.60 0.61 0.63 any(x % 2 for x in a) 0.36 0.36 0.36 0.37 0.37 any(True for x in a if x % 2)

¿Por qué la segunda forma es casi el doble de rápida?

Mi código de prueba:

 from timeit import repeat setup = 'a = [0] * 10000000' expressions = [ 'any(x % 2 for x in a)', 'any(True for x in a if x % 2)', ] for expression in expressions: times = sorted(repeat(expression, setup, number=1)) print(*('%.2f ' % t for t in times), expression)

¡Pruébelo en línea!

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

El primer método envía todo a any() mientras que el segundo solo envía a any() cuando hay un número impar, por lo que any() tiene menos elementos para pasar.

over 4 years ago · Santiago Trujillo Report

0

(x % 2 for x in a)

Este generador produce una serie de valores falsos hasta que produce un valor verdadero (si lo hace), momento en el que any dejará de iterar el generador y devolverá True .

 (True for x in a if x % 2)

Este generador solo producirá exactamente un valor True (si lo hace), momento en el que any detendrá la iteración y devolverá True .

El ir y venir adicional de ceder a any y luego obtener el siguiente valor del generador en el primer caso representa la sobrecarga.

over 4 years ago · Santiago Trujillo Report

0

TL; DR La versión lenta tiene que iterar sobre una larga secuencia de valores falsos antes de devolver False . La versión rápida "itera" sobre una secuencia vacía antes de hacer lo mismo. La diferencia es el tiempo que se tarda en construir la secuencia larga y falsa frente a la secuencia vacía.


Veamos el código de bytes generado por cada uno. He omitido la primera sección para cada uno, ya que son idénticos para ambos. Es solo el código de los generadores involucrados lo que necesitamos mirar.

 In [5]: dis.dis('any(x%2 for x in a)') [...] Disassembly of <code object <genexpr> at 0x105e860e0, file "<dis>", line 1>: 1 0 LOAD_FAST 0 (.0) >> 2 FOR_ITER 14 (to 18) 4 STORE_FAST 1 (x) 6 LOAD_FAST 1 (x) 8 LOAD_CONST 0 (2) 10 BINARY_MODULO 12 YIELD_VALUE 14 POP_TOP 16 JUMP_ABSOLUTE 2 >> 18 LOAD_CONST 1 (None) 20 RETURN_VALUE In [6]: dis.dis('any(True for x in a if x % 2)') [...] Disassembly of <code object <genexpr> at 0x105d993a0, file "<dis>", line 1>: 1 0 LOAD_FAST 0 (.0) >> 2 FOR_ITER 18 (to 22) 4 STORE_FAST 1 (x) 6 LOAD_FAST 1 (x) 8 LOAD_CONST 0 (2) 10 BINARY_MODULO 12 POP_JUMP_IF_FALSE 2 14 LOAD_CONST 1 (True) 16 YIELD_VALUE 18 POP_TOP 20 JUMP_ABSOLUTE 2 >> 22 LOAD_CONST 2 (None) 24 RETURN_VALUE

Ambos son idénticos hasta la instrucción BINARY_MODULO . Después de eso, la versión más lenta tiene que generar el valor resultante para que any lo consuma antes de continuar, mientras que el segundo código pasa inmediatamente al siguiente valor. Básicamente, el código más lento tiene que consumir una larga lista de valores falsos (es decir, distintos de cero) para determinar que no hay valores verdaderos. El código más rápido solo necesita consumir una lista vacía.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!