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 rangeser 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 xrangeen Python 2). Las respuestas por poke y por wim proporcionan el código fuente C relevante y explicaciones para aquellos que estén interesados.
rangees un generador?
xrangelo 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 rangeobjeto) y ahora también tiene county indexmétodos para que sea compatible con collections.SequenceABC.
boololongtipo, con otros tipos de objetos se volverá loco. Prueba con:100000000000000.0 in range(1000000000000001)