Qual é a diferença entre as funções range e xrange no Python 2.X?
aparentemente xrange é mais rápido, mas não faço ideia porque é mais rápido (e nenhuma prova além do anedótico até agora que é mais rápido) ou o que além disso é diferente sobre
for i in range(0, 20):
for i in xrange(0, 20):
28 answers
O intervalo cria uma lista, por isso se o fizer range(1, 10000000)
cria uma lista na memória com 9999999
Elementos.
xrange
é um objeto sequencial que avalia preguiçosamente.
Deve ser adicionado a partir da dica de @Thiago, que em python3, o intervalo faz o equivalente ao xrange
do pythonO intervalo cria uma lista, por isso se o fizer
range(1, 10000000)
cria uma lista na memória com9999999
elementos.
xrange
é um gerador, por issoé um objecto de sequênciaé um {[10] } que avalia preguiçosamente.
Isto é verdade, mas no Python 3, O range será implementado pelo Python 2 xrange(). Se você precisar gerar realmente a lista, você terá que fazer:
list(range(1,100))
Lembre-se, use o módulo timeit para testar qual dos pequenos fragmentos de código é mais rápido!
$ python -m timeit 'for i in range(1000000):' ' pass'
10 loops, best of 3: 90.5 msec per loop
$ python -m timeit 'for i in xrange(1000000):' ' pass'
10 loops, best of 3: 51.1 msec per loop
Pessoalmente, eu sempre uso range (), a menos que eu estivesse lidando com realmente listas enormes -- como você pode ver, em termos de tempo, para uma lista de um milhão de entradas, a sobrecarga extra é de apenas 0,04 segundos. E como Corey aponta, no Python 3.0 xrange irá embora E range lhe dará um bom comportamento iterador de qualquer maneira.
xrange
apenas armazena os parâmetros de gama e gera os números a pedido. No entanto, a implementação em C do Python restringe actualmente os seus args A C longs:
xrange(2**32-1, 2**32+1) # When long is 32 bits, OverflowError: Python int too large to convert to C long
range(2**32-1, 2**32+1) # OK --> [4294967295L, 4294967296L]
Note que no Python 3.0 existe apenas range
e comporta-se como o 2.x xrange
mas sem as limitações dos pontos finais mínimo e máximo.
O Xrange devolve um iterador e só mantém um número na memória de cada vez. o range mantém toda a lista de números na memória.
Passe algum tempo com a referência da Biblioteca . Quanto mais familiarizado você estiver com ele, mais rápido você pode encontrar respostas para perguntas como esta. Especialmente importantes são os primeiros capítulos sobre objetos e tipos de construção.
Outra forma de encontrar informações rápidas sobre uma construção em Python é a docstring e a função de Ajuda:A vantagem do tipo xrange é que um objecto xrange irá sempre pegue a mesma quantidade de memória, não importa o tamanho da faixa que representa. Não existem vantagens de desempenho consistentes.
print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)
Intervalo () vs xrange () em python :
Range () e xrange () são duas funções que podem ser usadas para iterar um certo número de vezes em loops em Python. No Python 3, não há xrange, mas a função range se comporta como o xrange no Python 2.Se quiser escrever um código que irá correr tanto no Python 2 como no Python 3, deverá usar o range ().
Range () - isto devolve uma lista de números criados com a função range ().
Xrange () - Esta função retorna o objeto gerador que pode ser usado para exibir números apenas por looping. Apenas uma gama particular é exibida sob demanda e, portanto, chamado de "avaliação preguiçosa".
Ambos são implementados de formas diferentes e têm características diferentes associadas a eles. Os pontos de comparação são:
- Devolve O Tipo Operação De Memória Velocidade De Utilização
- memória
- Utilização Da Operação
- Velocidade
1. Tipo De Devolução :
O Range () devolve – a lista como tipo de resposta.
O Xrange() devolve – o objecto xrange ().
# initializing a with range()
a = range(1,10000)
# initializing a with xrange()
x = xrange(1,10000)
# testing the type of a
print ("The return type of range() is : ")
print (type(a))
# testing the type of x
print ("The return type of xrange() is : ")
print (type(x))
Resultado :
The return type of range() is :
<type 'list'>
The return type of xrange() is :
<type 'xrange'>
2. Memória :
A variável que armazena o intervalo criado pelo range () toma mais memória do que a variável que armazena o intervalo usando o xrange (). A razão básica para isso é o tipo de retorno de range() é list e xrange() é objeto xrange ().
# initializing a with range()
a = range(1,10000)
# initializing a with xrange()
x = xrange(1,10000)
# testing the size of a
print ("The size allotted using range() is : ")
print (sys.getsizeof(a))
# testing the size of a
print ("The size allotted using xrange() is : ")
print (sys.getsizeof(x))
Resultado :
The size allotted using range() is :
80064
The size allotted using xrange() is :
40
3. Utilização das operações:
Como o range () devolve a lista, todas as operações que podem ser aplicadas na lista podem ser usadas nela. Por outro lado, como xrange() retorna o objeto xrange, as operações associadas à lista não podem ser aplicadas neles, daí uma desvantagem.
# Python code to demonstrate range() vs xrange()
# on basis of operations usage
# initializing a with range()
a = range(1,6)
# initializing a with xrange()
x = xrange(1,6)
# testing usage of slice operation on range()
print ("The list after slicing using range is : ")
print (a[2:5])
# testing usage of slice operation on xrange()
print ("The list after slicing using xrange is : ")
print (x[2:5])
Resultado :
The list after slicing using range is :
[3, 4, 5]
The list after slicing using xrange is :
Traceback (most recent call last):
File "pp.py", line 18, in <module>
print (x[2:5])
TypeError: sequence index must be integer, not 'slice'
4. Velocidade :
Devido ao facto de o xrange () avaliar apenas o objecto gerador contendo apenas os valores que são necessários pela avaliação preguiçosa, portanto é mais rápido na implementação do que a gama().
Pontos Importantes :
- Se quiser escrever um código que irá correr tanto no Python 2 como no Python 3, use range () as the xrange function is depreciated in Python 3.
- o intervalo () é mais rápido se iterar na mesma sequência múltiplos situacao.
- O xrange () tem de reconstruir o objecto inteiro sempre, mas o range () terá objectos inteiros reais. (It will always executar pior em termos de memória, no entanto).
Isto traz-lhe duas vantagens:O intervalo cria uma lista, por isso se você fizer o intervalo(1, 10000000) cria uma lista na memória com 10000000 elementos. xrange é um gerador, por isso avalia-se preguiçosamente.
- Você pode iterar listas mais longas sem obter um {[[0]}.
- como resolve cada número de forma preguiçosa, se parar a iteração mais cedo, não vai perder tempo a criar toda a lista.
Esta função é muito semelhante a
range()
, mas devolve um objectoxrange
em vez de uma lista. Este é um tipo de sequência opaca que produz os mesmos valores que a lista correspondente, sem realmente armazená-los todos simultaneamente. A vantagem dexrange()
sobrerange()
é mínima (uma vez quexrange()
ainda tem de criar os valores quando lhes é pedido) excepto quando é usada uma gama muito grande numa máquina sem memória ou quando todas as os elementos do range nunca são usados (como quando o laço é normalmente terminado combreak
).
O intervalo () irá criar uma lista de valores do início ao fim (0 .. 20 no seu exemplo). Esta operação tornar-se-á uma operação dispendiosa em gamas muito grandes.
Xrange () por outro lado é muito mais optimizado. ele só irá calcular o próximo valor quando necessário (através de um objeto de sequência xrange) e não cria uma lista de todos os valores como range() faz.
Encontrará a vantagem de xrange
sobre {[3] } Neste exemplo simples:
import timeit
t1 = timeit.default_timer()
a = 0
for i in xrange(1, 100000000):
pass
t2 = timeit.default_timer()
print "time taken: ", (t2-t1) # 4.49153590202 seconds
t1 = timeit.default_timer()
a = 0
for i in range(1, 100000000):
pass
t2 = timeit.default_timer()
print "time taken: ", (t2-t1) # 7.04547905922 seconds
O exemplo acima não reflecte nada substancialmente melhor no caso de xrange
.
Agora olhe para o seguinte caso em que range
é realmente muito lento, em comparação com xrange
.
import timeit
t1 = timeit.default_timer()
a = 0
for i in xrange(1, 100000000):
if i == 10000:
break
t2 = timeit.default_timer()
print "time taken: ", (t2-t1) # 0.000764846801758 seconds
t1 = timeit.default_timer()
a = 0
for i in range(1, 100000000):
if i == 10000:
break
t2 = timeit.default_timer()
print "time taken: ", (t2-t1) # 2.78506207466 seconds
Com range
, já cria uma lista de 0 a 100000000 (demorado), mas xrange
é um gerador e só gera números com base na necessidade, isto é, se a iteração continuo.
Em Python-3, a implementação do range
funcionalidade é a mesma que a do xrange
em Python-2, enquanto eles abandonaram xrange
em Python-3
O Range (): o range (1, 10) devolve uma lista de 1 a 10 números e mantém a lista completa na memória.
O Xrange (): Como o range (), mas em vez de devolver uma lista, devolve um objecto que gera os números no range a pedido. Para looping, este é levemente mais rápido do que alcance() e mais eficiente de memória. objeto xrange() como um iterador e gera os números sob demanda.(Avaliação Preguiçosa)
In [1]: range(1,10)
Out[1]: [1, 2, 3, 4, 5, 6, 7, 8, 9]
In [2]: xrange(10)
Out[2]: xrange(10)
In [3]: print xrange.__doc__
xrange([start,] stop[, step]) -> xrange object
range(x,y)
devolve uma lista de cada número entre x e y se usar um laço for
, então range
é mais lento. Na verdade, range
tem um índice maior. range(x.y)
irá imprimir uma lista de todos os números entre x e y
xrange(x,y)
devolve xrange(x,y)
mas se usou um laço for
, então xrange
é mais rápido. xrange
tem um índice menor. xrange
não só vai imprimir {[[7]} mas ainda vai manter todos os números que estão nele.
[In] range(1,10)
[Out] [1, 2, 3, 4, 5, 6, 7, 8, 9]
[In] xrange(1,10)
[Out] xrange(1,10)
Se usares um laço for
, então seria trabalho
[In] for i in range(1,10):
print i
[Out] 1
2
3
4
5
6
7
8
9
[In] for i in xrange(1,10):
print i
[Out] 1
2
3
4
5
6
7
8
9
Não há muita diferença ao usar loops, embora haja uma diferença quando apenas imprimi-lo!
Em python 2.x
O Range (x) devolve uma lista que é criada na memória com elementos X.
>>> a = range(5)
>>> a
[0, 1, 2, 3, 4]
O Xrange (x) devolve um objecto xrange que é um obj gerador que gera os números a pedido. eles são computados durante o for-loop (avaliação preguiçosa).
Para looping, isto é um pouco mais rápido do que o alcance() e mais eficiente de memória.
>>> b = xrange(5)
>>> b
xrange(5)
Ao testar o intervalo contra o xrange em loop (sei que devo usar timeit , mas isto foi rapidamente arrancado da memória usando um exemplo simples de compreensão da lista) encontrei o seguinte:
import time
for x in range(1, 10):
t = time.time()
[v*10 for v in range(1, 10000)]
print "range: %.4f" % ((time.time()-t)*100)
t = time.time()
[v*10 for v in xrange(1, 10000)]
print "xrange: %.4f" % ((time.time()-t)*100)
Que dá:
$python range_tests.py
range: 0.4273
xrange: 0.3733
range: 0.3881
xrange: 0.3507
range: 0.3712
xrange: 0.3565
range: 0.4031
xrange: 0.3558
range: 0.3714
xrange: 0.3520
range: 0.3834
xrange: 0.3546
range: 0.3717
xrange: 0.3511
range: 0.3745
xrange: 0.3523
range: 0.3858
xrange: 0.3997 <- garbage collection?
Ou, usando o xrange no laço for:
range: 0.4172
xrange: 0.3701
range: 0.3840
xrange: 0.3547
range: 0.3830
xrange: 0.3862 <- garbage collection?
range: 0.4019
xrange: 0.3532
range: 0.3738
xrange: 0.3726
range: 0.3762
xrange: 0.3533
range: 0.3710
xrange: 0.3509
range: 0.3738
xrange: 0.3512
range: 0.3703
xrange: 0.3509
O meu excerto está a ser testado correctamente? Algum comentário sobre a instância mais lenta do xrange? Ou melhor exemplo: -)
xrange
A range
. No entanto, a menos que você esteja usando 3.0 ou 3.1 (que ninguém deve ser), é realmente um tipo um pouco diferente.
Como o 3.1 docs diz:
Os objectos de gama têm muito pouco comportamento: só suportam indexação, iteração e a função
len
.
No entanto, em 3.2+, range
é uma sequência completa-suporta fatias estendidas, e tudo dos métodos de collections.abc.Sequence
com a mesma semântica que a list
.*
E, pelo menos em CPython e PyPy (as duas únicas implementações 3.2+ que existem atualmente), ele também tem implementações em tempo constante dos métodos index
e count
e do operador in
(desde que você só passe inteiros). Isso significa escrever 123456 in r
é razoável em 3.2+, enquanto em 2.7 ou 3.1 seria uma idéia horrível.
* o facto de issubclass(xrange, collections.Sequence)
retornar True
em 2, 6-2, 7 e 3.0-3.1 é um bug que foi fixado em 3.2 e não recuado.
Xrange () and range () in python works similarly as for the user , but the difference comes when we are talking about how the memory is allocated in using both the function.
Quando estamos a usar o intervalo () atribuímos memória para todas as variáveis que está a gerar, por isso não é recomendado usar com um no maior. de variáveis a serem geradas.
Xrange () por outro lado, gerar apenas um valor particular de cada vez e só pode ser usado com o laço for para imprimir todo o valores necessários.
O intervalo gera toda a lista e devolve-a. xrange não -- ele gera os números na lista sob demanda.
Leia o seguinte post para a comparação entre o intervalo e o xrange com a análise gráfica.
O Xrange usa um iterador (gera valores na altura), o intervalo devolve uma lista.
range
devolve uma lista estática à hora de execução.xrange
retorna um object
(que age como um gerador, embora certamente não seja um) a partir do qual os valores são gerados como e quando necessário.
Quando usar qual?
- Use
xrange
Se você quiser gerar uma lista para uma gama gigantesca, digamos 1 bilhão, especialmente quando você tem um "sistema sensível à memória" como um telefone celular. - utilize
range
se quiser iterar na lista várias situacao.
PS: Python 3.x's range
function = = Python 2.função de x xrange
.
Sobre a necessidade de varrimento/impressão de artigos 0-N , gama e fábricas de xrange como se segue.
Intervalo () - cria uma nova lista na memória e leva todos os itens 0 a N (Totalmente n+1) e imprime-os. xrange () - cria uma instância iteradora que varre os itens e mantém apenas o item encontrado na memória , portanto, utilizando a mesma quantidade de memória o tempo todo.
No caso de o elemento requerido estar um pouco no início da lista, só então ele economiza uma boa quantidade de tempo e memória.
A diferença diminui para argumentos menoresrange(..)
/ xrange(..)
:
$ python -m timeit "for i in xrange(10111):" " for k in range(100):" " pass"
10 loops, best of 3: 59.4 msec per loop
$ python -m timeit "for i in xrange(10111):" " for k in xrange(100):" " pass"
10 loops, best of 3: 46.9 msec per loop
Neste caso xrange(100)
é apenas cerca de 20% mais eficiente.
a=0
for i in range(1,100000):
a=a+i
E depois verificou a alteração na memória' em uso'. Foi insignificante. Então, eu corri o seguinte código:
for i in list(range(1,100000)):
a=a+i
E foi preciso uma grande parte da memória para ser usada, instantaneamente. E eu estava convencido.
Pode tentar por si mesmo.
Se estiver a usar o Python 2X, substitua "range ()" com "xrange ()" no primeiro código e "list (range ())" Com " range ()".
Intervalo retorna uma lista while xrange retorna uma xrange um objeto, que leva o mesmo de memória, independentemente do tamanho do intervalo,como neste caso,apenas um elemento é gerado e disponível em cada iteração considerando que, no caso de utilização de gama, todos os elementos são gerados de uma vez e estão disponíveis na memória.
Alcance :-alcance irá povoar tudo de uma vez.o que significa que cada número da Gama irá ocupar a memória.
Xrange: - xrange é algo como gerador, ele vai entrar em imagem quando você quer o intervalo de números, mas você não quer que eles sejam armazenados, como quando você quer usar para loop.so memória eficiente.Python 2.7.12
>>> print range.__doc__
range(stop) -> list of integers
range(start, stop[, step]) -> list of integers
Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns [0, 1, 2, 3]. The end point is omitted!
These are exactly the valid indices for a list of 4 elements.
>>> print xrange.__doc__
xrange(stop) -> xrange object
xrange(start, stop[, step]) -> xrange object
Like range(), but instead of returning a list, returns an object that
generates the numbers in the range on demand. For looping, this is
slightly faster than range() and more memory efficient.
Python 3. 5. 2
>>> print(range.__doc__)
range(stop) -> range object
range(start, stop[, step]) -> range object
Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).
>>> print(xrange.__doc__)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'xrange' is not defined
A diferença é aparente. Em Python 2.o x, range
devolve uma lista, xrange
devolve um objecto xrange que é iterável.
Em Python 3.x, range
torna-se xrange
do Python 2.x, and xrange
is removed.
Ver este Após para descobrir a diferença entre o intervalo e o xrange:
Para citar:
range
retorna exatamente o que você pensa: uma lista de consecutivos inteiros, com um comprimento definido a partir de 0.xrange
, no entanto, devolve um "objecto xrange" , que actua muito como um iterador