Tengo entendido que la range()
función, que en realidad es un tipo de objeto en Python 3 , genera su contenido sobre la marcha, similar a un generador.
Siendo este el caso, hubiera esperado que la siguiente línea tomara una cantidad excesiva de tiempo, porque para determinar si 1 billón está en el rango, se tendrían que generar un billón de valores:
1000000000000000 in range(1000000000000001)
Además: parece que no importa cuántos ceros agregue, el cálculo lleva más o menos la misma cantidad de tiempo (básicamente instantáneo).
También he intentado cosas como esta, pero el cálculo sigue siendo casi instantáneo:
1000000000000000000000 in range(0,1000000000000000000001,10) # count by tens
¡Si trato de implementar mi propia función de rango, el resultado no es tan bueno!
def my_crappy_range(N):
i = 0
while i < N:
yield i
i += 1
return
¿Qué está range()
haciendo el objeto debajo del capó que lo hace tan rápido?
La respuesta de Martijn Pieters fue elegida por su integridad, pero también puede ver la primera respuesta de abarnert para una buena discusión sobre lo que significa range
ser una secuencia completa en Python 3, y alguna información / advertencia sobre la inconsistencia potencial para la __contains__
optimización de la función en las implementaciones de Python . La otra respuesta de abarnert entra en más detalles y proporciona enlaces para aquellos interesados en la historia detrás de la optimización en Python 3 (y la falta de optimización xrange
en Python 2). Las respuestas por poke y por wim proporcionan el código fuente C relevante y explicaciones para aquellos que estén interesados.
range
es un generador?
xrange
lo mismo que python3range
?
xrange()
objetos @Superbest no tienen ningún __contains__
método, por lo que la verificación de elementos debe recorrer todos los elementos. Además, hay algunos otros cambios en range()
, al igual que apoya el corte en lonchas (que a su vez devuelve un range
objeto) y ahora también tiene count
y index
métodos para que sea compatible con collections.Sequence
ABC.
bool
olong
tipo, con otros tipos de objetos se volverá loco. Prueba con:100000000000000.0 in range(1000000000000001)