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

231
Vistas
Why is any (True for ... if cond) much faster than any (cond for ...)?

Two similar ways to check whether a list contains an odd number:

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

Timing results with a = [0] * 10000000 (five attempts each, times in seconds):

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)

Why is the second way almost twice as fast?

My testing code:

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)

Try it online!

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

0

The first method sends everything to any() whilst the second only sends to any() when there's an odd number, so any() has fewer elements to go through.

over 4 years ago · Santiago Trujillo Denunciar

0

(x % 2 for x in a)

This generator produces a series of falsey values until it produces a truthy value (if it does), at which point any will stop iterating the generator and return True.

(True for x in a if x % 2)

This generator will only produce exactly one True value (if it does), at which point any will stop the iteration and return True.

The additional back and forth of yielding back to any and then fetching the next value from the generator in the first case accounts for the overhead.

over 4 years ago · Santiago Trujillo Denunciar

0

TL;DR The slow version has to iterate over a long sequence of false values before returning False. The fast version "iterates" over an empty sequence before doing the same. The difference is the time it takes to construct the long-false sequence vs the empty sequence.


Let's look at the byte code generate by each. I've omitted the first section for each, as they are identical for the both. It's only the code for the generators involved that we need to look at.

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

Both are identical up to the BINARY_MODULO instruction. After that, the slower version has to yield the resulting value for any to consume before moving on, while the second code immediately moves on to the next value. So basically, the slower code has to consume a long list of false (i.e., non-zero) values to determine that there are no true values. The faster code only needs to consume an empty list.

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