Comprendo che la range()funzione, che in realtà è un tipo di oggetto in Python 3 , genera il suo contenuto al volo, simile a un generatore.
Stando così le cose, mi sarei aspettato che la seguente riga impiegasse una quantità eccessiva di tempo, perché per determinare se 1 quadrilione è compreso nell'intervallo, sarebbe necessario generare un quadrilione di valori:
1000000000000000 in range(1000000000000001)
Inoltre: sembra che non importa quanti zeri aggiungo, il calcolo richiede più o meno la stessa quantità di tempo (sostanzialmente istantaneo).
Ho anche provato cose del genere, ma il calcolo è ancora quasi istantaneo:
1000000000000000000000 in range(0,1000000000000000000001,10) # count by tens
Se provo ad implementare la mia funzione di intervallo, il risultato non è così bello !!
def my_crappy_range(N):
i = 0
while i < N:
yield i
i += 1
return
Cosa sta range()facendo l' oggetto sotto il cofano che lo rende così veloce?
La risposta di Martijn Pieters è stata scelta per la sua completezza, ma vedi anche la prima risposta di abarnert per una buona discussione su cosa significhi rangeessere una sequenza a tutti gli effetti in Python 3 e alcune informazioni / avvertenze riguardo a potenziali incoerenze per__contains__ ottimizzazione delle funzioni tra le implementazioni di Python . L'altra risposta di abarnert va in qualche dettaglio in più e fornisce collegamenti per coloro che sono interessati alla storia dietro l'ottimizzazione in Python 3 (e la mancanza di ottimizzazione xrangein Python 2). Le risposte di poke e di wim forniscono il codice sorgente C e le spiegazioni pertinenti per coloro che sono interessati.
rangeè un generatore?
xrangeuguale a Python3range ?
xrange()oggetti @Superbest non hanno alcun __contains__metodo, quindi il controllo degli articoli deve passare in rassegna tutti gli articoli. Inoltre ci sono alcune altre modifiche range(), come supporta lo slicing (che restituisce di nuovo un rangeoggetto) e ora ha anche counte indexmetodi per renderlo compatibile con collections.SequenceABC.
boololongtipo, con altri tipi di oggetto diventerà pazzo. Prova con:100000000000000.0 in range(1000000000000001)