Respostas:
No Python 2.x:
range
cria uma lista; portanto, se você fizer range(1, 10000000)
isso, cria uma lista na memória com 9999999
elementos.
xrange
é um objeto de sequência que avalia preguiçosamente.
No Python 3, range
faz o equivalente ao python xrange
e, para obter a lista, você precisa usar list(range(...))
.
xrange(x).__iter__()
é um gerador.
i
é avaliado sob demanda e não na inicialização.
range cria uma lista; portanto, se você fizer
range(1, 10000000)
isso, cria uma lista na memória com9999999
elementos.
xrange
é um gerador, portanto,é um objeto de sequência queéavaliado preguiçosamente.
Isso é verdade, mas no Python 3, .range()
será implementado pelo Python 2 .xrange()
. Se você realmente deseja gerar a lista, precisará:
list(range(1,100))
xrange
um gerador? É uma função que contém yield
instrução e, de acordo com o glossário, tais funções são chamadas de geradores.
Lembre-se, use o timeit
módulo para testar qual dos pequenos trechos 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 esteja lidando com listas realmente grandes - 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 aponta Corey, no Python 3.0 .xrange()
desaparecerá e .range()
fornecerá um bom comportamento do iterador de qualquer maneira.
python -m timeit "for i in xrange(1000000):" " pass"
the extra overhead is only 0.04 seconds
não é a maneira correta de ver isso, (90.5-51.1)/51.1 = 1.771 times slower
é correta porque indica que, se esse é o loop principal do seu programa, ele pode potencialmente estrangulá-lo. No entanto, se essa é uma parte pequena, 1,77x não é muito.
xrange
armazena apenas os parâmetros do intervalo e gera os números sob demanda. No entanto, a implementação C do Python atualmente restringe seus argumentos 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]
Observe que no Python 3.0 existe apenas range
e ele se comporta como o 2.x, xrange
mas sem as limitações nos pontos finais mínimos e máximos.
O xrange retorna um iterador e mantém apenas um número na memória por vez. O intervalo mantém toda a lista de números na memória.
xrange
se não retornar um iterador.
and only keeps one number in memory at a time
e onde o resto são colocados por favor me orientar ..
Passe algum tempo com a Referência da biblioteca . Quanto mais familiarizado, mais rápido você encontrará respostas para perguntas como essa. Especialmente importantes são os primeiros capítulos sobre objetos e tipos incorporados.
A vantagem do tipo xrange é que um objeto xrange sempre terá a mesma quantidade de memória, independentemente do tamanho do intervalo que ele representa. Não há vantagens consistentes de desempenho.
Outra maneira de encontrar informações rápidas sobre uma construção Python é a docstring e a função de ajuda:
print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)
Estou chocado que ninguém leu doc :
Essa função é muito semelhante a
range()
, mas retorna umxrange
objeto em vez de uma lista. Este é um tipo de sequência opaco que gera os mesmos valores da lista correspondente, sem realmente armazená-los todos simultaneamente. A vantagem doxrange()
excessorange()
é mínima (já quexrange()
ainda é necessário criar os valores quando solicitados), exceto quando uma faixa muito grande é usada em uma máquina com falta de memória ou quando todos os elementos da faixa nunca são usados (como quando o loop é geralmente termina combreak
).
range cria uma lista; portanto, se você fizer o range (1, 10000000), cria uma lista na memória com 10000000 elementos. xrange é um gerador, por isso avalia preguiçosamente.
Isso traz duas vantagens:
MemoryError
.Você encontrará a vantagem de xrange
terminar range
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 reflete nada substancialmente melhor em caso de xrange
.
Agora, observe 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
, ele já cria uma lista de 0 a 100000000 (demorada), mas xrange
é um gerador e gera apenas números com base na necessidade, ou seja, se a iteração continuar.
No Python-3, a implementação da range
funcionalidade é igual à do xrange
Python-2, enquanto eles acabaram com o xrange
Python-3
Feliz codificação !!
É por razões de otimização.
range () criará uma lista de valores do início ao fim (0 .. 20 no seu exemplo). Isso se tornará uma operação cara em faixas muito grandes.
xrange () por outro lado, é muito mais otimizado. ele calculará apenas o próximo valor quando necessário (por meio de um objeto de sequência xrange) e não cria uma lista de todos os valores, como range ().
range(x,y)
retorna uma lista de cada número entre x e y, se você usar um for
loop, range
é mais lento. De fato, range
possui uma faixa maior de índice. range(x.y)
imprimirá uma lista de todos os números entre x e y
xrange(x,y)
retorna, xrange(x,y)
mas se você usou um for
loop, então xrange
é mais rápido. xrange
tem um intervalo menor de índice. xrange
não apenas será impresso, xrange(x,y)
mas também manterá todos os números contidos nele.
[In] range(1,10)
[Out] [1, 2, 3, 4, 5, 6, 7, 8, 9]
[In] xrange(1,10)
[Out] xrange(1,10)
Se você usar um for
loop, funcionaria
[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 exista uma diferença ao apenas imprimi-lo!
range (): range (1, 10) retorna uma lista de 1 a 10 números e mantém a lista inteira na memória.
xrange (): como range (), mas em vez de retornar uma lista, retorna um objeto que gera os números no intervalo sob demanda. Para loop, isso é levemente mais rápido que o range () e mais eficiente em memória. xrange () como um iterador e gera os números sob demanda. (Lazy Evaluation)
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
Algumas das outras respostas mencionam que o Python 3 eliminou o 2.x range
e renomeou o 2.x xrange
pararange
. No entanto, a menos que você esteja usando 3.0 ou 3.1 (que ninguém deveria estar), na verdade é um tipo um pouco diferente.
Como dizem os documentos 3.1 :
Os objetos Range têm muito pouco comportamento: eles suportam apenas indexação, iteração e
len
função.
No entanto, no 3.2+, range
é uma sequência completa - ele suporta fatias estendidas e todos os métodos collections.abc.Sequence
com a mesma semântica que a list
. *
E, pelo menos em CPython e PyPy (os únicos dois 3.2+ implementações que existem atualmente), ele também tem implementações em tempo constante do index
e count
métodos e o in
operador (contanto que você só passá-lo inteiros). Isso significa que a escrita 123456 in r
é razoável em 3.2+, enquanto em 2.7 ou 3.1 seria uma ideia horrível.
* O fato de issubclass(xrange, collections.Sequence)
retornar True
em 2.6-2.7 e 3.0-3.1 é um bug corrigido no 3.2 e não suportado.
No python 2.x
range (x) retorna uma lista criada na memória com x elementos.
>>> a = range(5)
>>> a
[0, 1, 2, 3, 4]
xrange (x) retorna um objeto xrange que é um objeto gerador que gera os números sob demanda. eles são calculados durante o loop for (Lazy Evaluation).
Para loop, isso é um pouco mais rápido que o range () e mais eficiente em memória.
>>> b = xrange(5)
>>> b
xrange(5)
xrange()
não é um gerador. xrange(n)
.__ iter __ () `é.
Ao testar o intervalo contra o xrange em um loop (eu sei que devo usar o timeit , mas isso foi rapidamente hackeado da memória usando um exemplo simples de compreensão de 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 xrange no loop 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
Meu snippet está testando corretamente? Algum comentário sobre a instância mais lenta do xrange? Ou um exemplo melhor :-)
xrange
pareceu um pouco mais rápida, embora no Python 3 a comparação agora seja redundante.
timeit
serve. Ela cuida de correr muitas vezes, incapacitante GC, usando o melhor relógio em vez de time
, etc.
xrange () e range () em python funcionam da mesma forma que para o usuário, mas a diferença ocorre quando estamos falando sobre como a memória é alocada no uso da função.
Quando estamos usando range (), alocamos memória para todas as variáveis que estão gerando, portanto, não é recomendável usar com número maior. de variáveis a serem geradas.
xrange () por outro lado, gera apenas um valor específico de cada vez e só pode ser usado com o loop for para imprimir todos os valores necessários.
O intervalo gera a lista inteira e a retorna. O xrange não - ele gera os números na lista sob demanda.
O que?
range
retorna uma lista estática em tempo 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?
xrange
se você deseja gerar uma lista para uma faixa gigantesca, digamos 1 bilhão, especialmente quando você tem um "sistema sensível à memória", como um telefone celular.range
se você quiser percorrer a lista várias vezes.PS: do Python 3.x range
função == do Python 2.x xrange
função.
xrange
não retorna um objeto gerador.
Todo mundo explicou muito. Mas eu queria que ele visse por mim mesmo. Eu uso python3. Então, abri o monitor de recursos (no Windows!) E, primeiro, executei o seguinte comando primeiro:
a=0
for i in range(1,100000):
a=a+i
e depois verificou a alteração na memória 'Em uso'. Foi insignificante. Em seguida, executei o seguinte código:
for i in list(range(1,100000)):
a=a+i
E foi preciso grande parte da memória para uso instantaneamente. E eu estava convencido. Você pode tentar por si mesmo.
Se você estiver usando o Python 2X, substitua 'range ()' por 'xrange ()' no primeiro código e 'list (range ())' por 'range ()'.
Dos documentos de ajuda.
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. No Python 2.x, range
retorna uma lista, xrange
retorna um objeto xrange que é iterável.
No Python 3.x, range
passa a ser xrange
do Python 2.xe xrange
é removido.
Em um requisito para digitalização / impressão de itens 0-N, o intervalo e o intervalo variam da seguinte maneira.
range () - cria uma nova lista na memória e pega todos os itens de 0 a N (totalmente N + 1) e os imprime. xrange () - cria uma instância do iterador que varre os itens e mantém apenas o item encontrado na memória, utilizando a mesma quantidade de memória o tempo todo.
Caso o elemento requerido esteja apenas no início da lista, ele economiza uma boa quantidade de tempo e memória.
xrange
não cria uma instância do iterador. Ele cria um xrange
objeto que é iterável, mas não um iterador - quase (mas não exatamente) uma sequência, como uma lista.
Range retorna uma lista enquanto xrange retorna um objeto xrange que usa a mesma memória, independentemente do tamanho do intervalo, pois nesse caso, apenas um elemento é gerado e disponível por iteração, enquanto que no caso de usar o intervalo, todos os elementos são gerados de uma só vez e estão disponíveis na memória.
A diferença diminui para argumentos menores para range(..)
/ 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
Nesse caso, xrange(100)
é apenas 20% mais eficiente.
range: -range irá preencher tudo de uma vez. o que significa que todos os números do intervalo ocuparão a memória.
xrange: -xrange é algo como gerador, ele aparece em imagem quando você deseja o intervalo de números, mas não deseja que eles sejam armazenados, como quando você deseja usar o loop.so, com eficiência de memória.
range()
em Python 2.x
Essa função é essencialmente a range()
função antiga que estava disponível no Python 2.x
e retorna uma instância de um list
objeto que contém os elementos no intervalo especificado.
No entanto, essa implementação é muito ineficiente quando se trata de inicializar uma lista com um intervalo de números. Por exemplo, for i in range(1000000)
seria um comando muito caro para executar, tanto em termos de memória quanto de uso do tempo, pois requer o armazenamento dessa lista na memória.
range()
em Python 3.x
e xrange()
em Python2.x
O Python 3.x
introduziu uma implementação mais nova de range()
(enquanto a implementação mais recente já estava disponível no Python 2.x
através doxrange()
função).
O range()
explora uma estratégia conhecida como avaliação preguiçosa. Em vez de criar uma lista enorme de elementos no intervalo, a implementação mais recente apresenta a classe range
, um objeto leve que representa os elementos necessários no intervalo especificado, sem armazená-los explicitamente na memória (isso pode parecer geradores, mas o conceito de avaliação lenta é diferente).
Como exemplo, considere o seguinte:
# Python 2.x
>>> a = range(10)
>>> type(a)
<type 'list'>
>>> b = xrange(10)
>>> type(b)
<type 'xrange'>
e
# Python 3.x
>>> a = range(10)
>>> type(a)
<class 'range'>
Veja este post para encontrar a diferença entre range e xrange:
Citar:
range
retorna exatamente o que você pensa: uma lista de números inteiros consecutivos, com um comprimento definido começando com 0.xrange
, no entanto, retorna um "objeto xrange" , que atua muito como um iterador
xrange
não é um iterador. A lista retornada por range
suporta iteração (uma lista é praticamente o exemplo prototípico de uma iterável). O benefício geral de xrange
não é "mínimo". E assim por diante.