it-swarm-tr.com

Python 2.X'te range ve xrange işlevleri arasındaki fark nedir?

Görünüşe göre xrange daha hızlı ancak neden daha hızlı olduğu (ve anekdottan daha hızlı olduğu kadar kanıt olmadığını da) ya da bunun neden farklı olduğu hakkında hiçbir fikrim yok.

for i in range(0, 20):
for i in xrange(0, 20):
644
Teifion

range bir liste oluşturur; bu nedenle range(1, 10000000) işlevini yaparsanız, 9999999 öğeleriyle bellekte bir liste oluşturur.

xrange tembel olarak değerlendiren bir dizi nesnesidir. 

@ Thiago'ın ​​ipucundan eklenmelidir, python3'te, aralık python'un xrange değerine eşittir. 

735
Charles

range bir liste oluşturur, bu yüzden range(1, 10000000) yaparsanız bellekte 9999999 elementler ile bir liste oluşturur.

xrangename__ bu bir jeneratör, yani sıra nesnesidir bir Bu tembelce değerlendirir.

Bu doğrudur, ancak Python 3, .range(), Python 2 .xrange() tarafından uygulanacaktır. Listeyi gerçekten oluşturmanız gerekiyorsa, yapmanız gerekenler:

list(range(1,100))
218
Corey

Unutmayın, küçük kod parçacıklarından hangisinin daha hızlı olduğunu test etmek için timeit modülünü kullanın!

$ 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

Şahsen, her zaman .range() işlevini kullanırım, really huge listeleriyle uğraşmadığım sürece - görebildiğiniz gibi, zaman içerisinde, milyonlarca girişin bir listesi için, fazladan ek ücret sadece 0.04 saniyedir. Corey'in işaret ettiği gibi, Python 3.0'da .xrange() kaybolur ve .range() yine de Nice yineleyici davranışı verir.

103
John Fouhy

xrange, yalnızca aralık paramanlarını depolar ve isteğe bağlı sayıları oluşturur. Bununla birlikte, Python'un C uygulaması şu an için uzun süredir C uzunluğunu sınırlamaktadır:

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]

Python 3.0'da yalnızca range olduğunu ve 2.x xrange gibi davrandığını, ancak minimum ve maksimum bitiş noktalarında sınırlama olmadan bulunduğunu unutmayın.

64
efotinis

xrange bir yineleyici döndürür ve bir seferde yalnızca bir sayıyı bellekte tutar. range, tüm numaraların listesini bellekte tutar.

38
Ben Hoffstein

Library Reference ile biraz zaman geçirin. Ne kadar aşina olursan, bu gibi soruların cevaplarını o kadar hızlı bulabilirsin. Özellikle önemli yerleşik nesneler ve türleri hakkında ilk birkaç bölüm.

Xrange türünün avantajı, xrange nesnesinin her zaman temsil ettiği aralığın boyutu ne olursa olsun, aynı miktarda belleği alın. Tutarlı performans avantajı yoktur.

Bir Python yapısı hakkında hızlı bilgi bulmanın bir başka yolu da dokümantasyon ve yardım işlevidir:

print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)
28
Antti Rasinen

Şoke oldum kimsenin okumaması doc :

Bu işlev range() işlevine çok benzer, ancak liste yerine xrange nesnesini döndürür. Bu, aslında hepsini aynı anda kaydetmeden, karşılık gelen listeyle aynı değerleri veren bir opak dizi türüdür. xrange() işlevinin range() yerine avantajı minimumdur (çünkü xrange() hala bellek açlıklı bir makinede çok geniş bir aralık kullanılırsa veya aralığın tüm öğelerinin hiç kullanılmadığı durumlar dışında) döngü genellikle break ile sonlandırılır).

13
Kishor Pawar

aralık bir liste oluşturur; bu nedenle aralık yaparsanız (1, 10000000), bellekte 10000000 öğelerden oluşan bir liste oluşturur. xrange bir jeneratördür, bu yüzden tembel olarak değerlendirir.

Bu size iki avantaj sağlar:

  1. MemoryError almadan daha uzun listeleri yineleyebilirsiniz.
  2. Her sayı tembel olarak çözüldüğü için, yinelemeyi erken durdurursanız, tüm listeyi oluşturmak için zaman kaybetmezsiniz.
12
Lucas S.

Optimizasyon nedenlerinden dolayı.

range (), baştan sona bir değer listesi oluşturur (örneğinizde 0 .. 20). Bu, çok geniş aralıklarda pahalı bir işlem haline gelecektir.

Öte yandan, xrange () işlevi çok daha optimize edilmiştir. bir sonraki değeri yalnızca gerektiğinde (bir xrange dizisi nesnesiyle) hesaplar ve range () gibi tüm değerlerin bir listesini oluşturmaz.

10
QAZ

Bu basit örnekte xrange'nin range yerine avantajını bulacaksınız:

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

Yukarıdaki örnek xrange durumunda büyük ölçüde daha iyi bir şey yansıtmamaktadır.

Şimdi range öğesinin xrange ile karşılaştırıldığında gerçekten çok yavaş olduğu aşağıdaki duruma bakın.

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

range ile zaten 0 - 100000000 (zaman alıcı) arasında bir liste oluşturur, ancak xrange bir jeneratördür ve yalnızca ihtiyaca göre, yani yineleme devam ederse sayılar oluşturur.

Python-3'te, range işlevinin uygulanması Python-2'deki xrange ile aynıdır, Python-3'te xrange ile işlem tamamlanırken

Mutlu Kodlama !! 

10
User_Targaryen

range (): range (1, 10), 1 ile 10 arasında bir sayı verir ve tüm listeyi bellekte tut.

xrange (): Like range (), ancak bir liste döndürmek yerine, istenen aralıktaki sayıları üreten nesneyi döndürür. Döngü için, bu range () hafifçe daha hızlı ve daha verimli bellek . xrange () bir yineleyici gibi nesne ve talep üzerine sayıları üretir. (Tembel Değerlendirme)

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
8
Tushar.PUCSD

range(x,y), eğer bir for döngüsü kullanıyorsanız, x ve y arasındaki her sayının bir listesini döndürür, ardından range daha yavaş olur. Aslında, range daha büyük bir İndeks aralığına sahiptir. range(x.y), x ve y arasındaki tüm sayıların bir listesini basar

xrange(x,y), xrange(x,y) değerini döndürür, ancak for döngüsünü kullanırsanız, xrange daha hızlıdır. xrange, daha küçük bir İndeks aralığına sahiptir. xrange yalnızca xrange(x,y) dosyasını yazdırmaz, aynı zamanda içinde bulunan tüm sayıları da tutar.

[In] range(1,10)
[Out] [1, 2, 3, 4, 5, 6, 7, 8, 9]
[In] xrange(1,10)
[Out] xrange(1,10)

for döngüsünü kullanırsanız işe yarar

[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

Döngüleri kullanırken fazla bir fark yoktur, ancak sadece yazdırırken bir fark vardır!

8
Supercolbat

Python 2.x'te

range (x) , x öğeleriyle bellekte oluşturulan bir liste döndürür.

>>> a = range(5)
>>> a
[0, 1, 2, 3, 4]

xrange (x) , talep edilen sayıları üreten bir üreteci obj olan xrange nesnesini döndürür. Onlar for-loop sırasında hesaplanır (Tembel Değerlendirme).

Döngü için, bu range () değerinden biraz daha hızlıdır ve daha fazla bellek verimlidir.

>>> b = xrange(5)
>>> b
xrange(5)
6
SrmHitter9062

Döngüdeki xrange'e karşı aralığı sınarken ( timeit kullanmam gerektiğini biliyorum, ancak bu basit bir liste anlama örneği kullanılarak bellekten derhal kesildi)

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)

hangi verir:

$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?

Veya for loop'da xrange kullanarak:

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

Snippet testim doğru mu? Daha yavaş xrange örneği hakkında herhangi bir yorumunuz var mı? Veya daha iyi bir örnek :-)

5
Dave Everitt

Diğer cevaplardan bazıları Python 3'ün 2.x'in range'sini ortadan kaldırdığını ve 2.x'in xrange ile range olarak değiştirdiğini belirtiyor. Ancak, 3.0 veya 3.1 kullanmıyorsanız (ki bu hiç kimsenin olmaması gerekir), aslında biraz farklı bir tür.

3.1 dokümanlar dediği gibi:

Range nesneleri çok az davranışa sahiptir: yalnızca dizin oluşturmayı, yinelemeyi ve len işlevini destekler.

Ancak, 3.2+ sürümünde range tam bir sekanstır - genişletilmiş dilimleri ve tüm collections.abc.Sequence yöntemlerini list ile aynı anlambilimiyle destekler.*

Ve en azından CPython ve PyPy'de (şu anda var olan sadece iki 3.2+ uygulama), ayrıca index ve count yöntemlerinin ve in operatörünün (yalnızca tamsayıları geçtiği sürece) sabit zamanlı uygulamaları vardır. Bu, 123456 in r yazmanın 3.2+ 'de makul olduğu, 2.7 veya 3.1' de ise korkunç bir fikir olduğu anlamına gelir.


* issubclass(xrange, collections.Sequence) öğesinin 2.6-2.7 ve 3.0-3.1'deki True değerini döndürmesi, 3.2'de düzeltilen ve desteklenmeyen bir hatadır .

5
abarnert

python'daki xrange () ve range (), kullanıcı için benzer şekilde çalışır, ancak fark, her iki işlevi de kullanarak belleğin nasıl tahsis edildiğinden bahsederken ortaya çıkar.

Range () işlevini kullanırken, ürettiği tüm değişkenler için bellek ayırırız, bu nedenle daha büyük olan hayır ile kullanılması önerilmez. üretilecek değişkenlerin sayısı.

xrange () ise bir seferde yalnızca belirli bir değer üretir ve sadece gerekli tüm değerleri yazdırmak için for döngüsü ile kullanılabilir.

4

Grafik analizi ile aralık ve xrange arasındaki karşılaştırma için aşağıdaki yazıyı okuyun.

Python aralığı Vs xrange

3
Harsha Vardhan

range listenin tamamını oluşturur ve geri döndürür. xrange yapmaz - isteğe bağlı olarak listedeki sayıları oluşturur.

3
Eddie Deyo

Ne?
range çalışma zamanında statik bir liste döndürür.
xrange, değerlerin gerektiği şekilde ve gerektiğinde üretildiği bir object (bir jeneratör gibi davranır, kesinlikle bir olmasa da) döndürür.

Hangisini ne zaman kullanmalı? 

  • Devasa bir aralık için bir liste oluşturmak istiyorsanız, özellikle bir cep telefonu gibi "belleğe duyarlı bir sistem" olduğunda 1 milyar deyin, xrange kullanın.
  • Listede birkaç kez yineleme yapmak istiyorsanız range kullanın.

PS: Python 3.x'in range işlevi == Python 2.x'in xrange işlevi.

2
kmario23

xrange bir yineleyici kullanır (anında değerler üretir), aralık bir liste döndürür.

2
hacama

Küçük argümanlar için fark range(..)/xrange(..) 'a düşer:

$ 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

Bu durumda xrange(100) sadece% 20 daha verimlidir.

1
Evgeni Sergeev

0 N öğelerin taranması/yazdırılması zorunluluğu üzerine, menzil ve xrange aşağıdaki gibi çalışır.

range () - bellekte yeni bir liste oluşturur ve 0'dan N'ye kadar olan tüm öğeleri alır (tamamen N + 1) ve bunları yazdırır . xrange () - öğeleri tarayan ve yalnızca geçerli olan bir yineleyici örneği oluşturur belleğe rastlanan öğe, bu nedenle her zaman aynı miktarda bellek kullanır.

İstenilen öğenin listenin başında bir miktar olması durumunda, iyi bir zaman ve hafıza tasarrufu sağlar.

1
SomeDoubts

Herkes bunu çok iyi açıkladı. Ama kendim için görmesini istedim. Python3 kullanıyorum. Böylece, kaynak izleyicisini açtım (Windows'ta!) Ve önce ilk önce aşağıdaki komutu uyguladım:

a=0
for i in range(1,100000):
    a=a+i

ve sonra 'Kullanımda' hafızasındaki değişikliği kontrol etti. Önemsizdi .. Sonra aşağıdaki kodu koştum:

for i in list(range(1,100000)):
    a=a+i

Ve anında, kullanım için büyük miktarda bellek aldı. Ve ikna olmuştum . Kendin deneyebilirsin.

Python 2X kullanıyorsanız, ilk koddaki 'range ()' yerine 'xrange ()' ve 'range ()' ile 'list (range ())' yazın.

1
ANKUR SATYA

Yardım dokümanlarından.

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

Fark açıktır. Python 2.x'te range bir liste, xrange ise yinelenebilen bir xrange nesnesi döndürür.

Python 3.x'te range, Python 2.x'in xrange olur ve xrange kaldırılır.

0
Rajendra Uppal

Range, list değerini döndürürken, xrange, aralık boyutuna bakılmaksızın aynı belleği alan bir xrange nesnesi döndürür, bu durumda olduğu gibi, yalnızca aralık kullanılması durumunda, tüm elemanlar bir kerede üretilir ve bellekte bulunur.

0
user299567

range: -range her şeyi bir kerede doldurur. Bu, aralıktaki her sayının belleği kaplayacağı anlamına gelir.

xrange: -xrange, jeneratör gibi bir şeydir, sayı aralığını istediğinizde resme gelir, ancak loop.so belleği için kullanmak istediğinizde olduğu gibi, bunların saklanmasını istemezsiniz.

0
tejaswini teju

Ek olarak, eğer list(xrange(...)), range(...) ile eşdeğer olacaktır.

Yani list yavaş.

Ayrıca xrange gerçekten tam olarak diziyi tamamlamıyor

Bu yüzden bir liste değil, xrange bir nesne.

0
U9-Forward