Python Language Differenze tra le funzioni range e xrange


Esempio

In Python 2, la funzione range restituisce un elenco mentre xrange crea un oggetto xrange speciale, che è una sequenza immutabile, che a differenza di altri tipi di sequenza incorporati, non supporta l'slicing e non ha né index né metodi di count :

Python 2.x 2.3
print(range(1, 10))
# Out: [1, 2, 3, 4, 5, 6, 7, 8, 9]

print(isinstance(range(1, 10), list))
# Out: True

print(xrange(1, 10))
# Out: xrange(1, 10)

print(isinstance(xrange(1, 10), xrange))
# Out: True

In Python 3, xrange stato espanso alla sequenza di range , che ora crea un oggetto range . Non esiste un tipo xrange :

Python 3.x 3.0
print(range(1, 10))
# Out: range(1, 10)

print(isinstance(range(1, 10), range))
# Out: True

# print(xrange(1, 10))
# The output will be:
#Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
#NameError: name 'xrange' is not defined

Inoltre, dal momento che Python 3.2, range supporta anche affettare, index e count :

print(range(1, 10)[3:7])
# Out: range(3, 7)
print(range(1, 10).count(5))
# Out: 1
print(range(1, 10).index(7))
# Out: 6

Il vantaggio di usare un tipo di sequenza speciale invece di una lista è che l'interprete non deve allocare memoria per un elenco e popolarlo:

Python 2.x 2.3
# range(10000000000000000)
# The output would be:
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# MemoryError

print(xrange(100000000000000000))
# Out: xrange(100000000000000000)

Poiché il secondo comportamento è generalmente desiderato, il primo è stato rimosso in Python 3. Se vuoi comunque avere un elenco in Python 3, puoi semplicemente usare il costruttore di list() su un oggetto range :

Python 3.x 3.0
print(list(range(1, 10)))
# Out: [1, 2, 3, 4, 5, 6, 7, 8, 9]

Compatibilità

Per mantenere la compatibilità tra le versioni di Python 2.xe di Python 3.x, è possibile utilizzare il modulo builtins dal pacchetto esterno future per ottenere sia compatibilità builtins compatibilità all'indietro :

Python 2.x 2.0
#forward-compatible
from builtins import range

for i in range(10**8):
    pass
Python 3.x 3.0
#backward-compatible
from past.builtins import xrange

for i in xrange(10**8):
    pass

L' range nella future libreria supporta slicing, index e count in tutte le versioni di Python, proprio come il metodo built-in su Python 3.2+.