Yanıtlar:
Python 2.x'te:
rangebir liste oluşturur, böylece yaparsanız range(1, 10000000)bellekteki 9999999öğelerle birlikte bir liste oluşturur .
xrange tembel olarak değerlendirilen bir dizi nesnesidir.
Python 3'te, rangepython'lara eşdeğerdir xrangeve listeyi almak için kullanmanız gerekir list(range(...)).
xrange(x).__iter__()bir jeneratördür.
ibaşlatma yerine talep üzerine değerlendirildiği anlamına gelir .
aralık bir liste oluşturur, bu nedenle bunu yaparsanız
range(1, 10000000)bellekteki9999999öğeleri içeren bir liste oluşturur .
xrangeBir jeneratör, bu nedenlebir dizi amacı,a,bu değerlendirir lazily.
Bu doğrudur, ancak Python 3'te .range()Python 2 tarafından uygulanacaktır .xrange(). Listeyi gerçekten oluşturmanız gerekiyorsa yapmanız gerekenler:
list(range(1,100))
Unutmayın, timeithangi küçük kod parçacıklarının daha hızlı olduğunu test etmek için modülü 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 kullanıyorum .range(), gerçekten büyük listelerle uğraşmadıkça - gördüğünüz gibi, bir milyon giriş listesi için, zamana göre, ek yük sadece 0.04 saniyedir. Ve Corey'nin işaret ettiği gibi, Python 3.0'da .xrange()gidecek ve .range()yine de size güzel yineleyici davranışı verecektir.
python -m timeit "for i in xrange(1000000):" " pass"
the extra overhead is only 0.04 secondsona bakmanın doğru yolu değil, (90.5-51.1)/51.1 = 1.771 times slowerdoğru çünkü programınızın çekirdek döngüsü ise potansiyel olarak tıkanabilir. Ancak, bu küçük bir parça ise 1.77x fazla değildir.
xrangesadece aralık parametrelerini saklar ve talep üzerine sayıları üretir. Ancak Python'un C uygulaması şu anda argümanlarını C uzunlarıyla kısıtlıyor:
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 sadece rangeve bunun 2.x gibi davrandığını, xrangeancak minimum ve maksimum bitiş noktalarında sınırlama olmadığını unutmayın.
xrange bir yineleyici döndürür ve aynı anda yalnızca bir sayıyı bellekte tutar. aralık, tüm sayılar listesini hafızada tutar.
xrangeyok değil bir yineleyici döndürür.
and only keeps one number in memory at a timeve geri kalanı nereye yerleştirilir lütfen bana yol göster ..
Kütüphane Referansı ile biraz zaman geçirin . Ne kadar aşina olursanız, bunun gibi soruların cevaplarını o kadar hızlı bulabilirsiniz. Yerleşik nesneler ve türler hakkında ilk birkaç bölüm özellikle önemlidir.
Xrange türünün avantajı, bir xrange nesnesinin temsil ettiği aralığın boyutu ne olursa olsun her zaman aynı miktarda bellek almasıdır. Tutarlı performans avantajları yoktur.
Python yapısı hakkında hızlı bilgi bulmanın başka bir yolu da docstring ve yardım fonksiyonudur:
print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)
Kimsenin doc okumasından şok oldum :
Bu işlev çok benzer
range(), ancakxrangeliste yerine bir nesne döndürür . Bu, hepsi aynı anda depolanmadan karşılık gelen listeyle aynı değerleri veren opak bir dizi türüdür. Avantajıxrange()üzerinderange()minimal (berixrange()aralığın elemanların tüm bu döngü olması gibi (hiç kullanılmamış zaman çok büyük bir aralık bir bellek-hasret makinede kullanılmış veya durumlar hariç onlar için sorulduğunda hala değerleri oluşturmak için vardır) genellikle ile sonlandırılırbreak).
aralık bir liste oluşturur, bu nedenle aralık (1, 10000000) yaparsanız, 10000000 öğeyle bellekte bir liste oluşturur. xrange bir jeneratördür, bu yüzden tembel olarak değerlendirir.
Bu size iki avantaj sağlar:
MemoryError.Bu basit örnekte xrangeaşırı avantajı bulacaksınız range:
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, durumunda daha iyi bir şey yansıtmamaktadır xrange.
Şimdi range, gerçekten yavaş olan aşağıdaki duruma bakın 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
İle range, zaten 0 ila 100000000 (zaman alıcı) arasında bir liste oluşturur, ancak xrangebir jeneratördür ve sadece ihtiyaca göre sayılar üretir, yani yineleme devam ederse.
Python-3'te, rangeişlevselliğin uygulanması xrangePython-2'deki ile aynıdır xrange, Python-3'te ise
Mutlu Kodlama !!
Optimizasyon nedenleriyle.
range (), baştan sona bir değerler listesi oluşturur (örneğinizde 0 .. 20). Bu, çok geniş aralıklarda pahalı bir operasyon haline gelecektir.
xrange () ise çok daha optimize edilmiştir. bir sonraki değeri yalnızca gerektiğinde (bir xrange dizi nesnesi aracılığıyla) hesaplar ve range () gibi tüm değerlerin bir listesini oluşturmaz.
range(x,y)bir fordöngü kullanırsanız x ile y arasındaki her sayının bir listesini döndürür , o rangezaman yavaştır. Aslında, rangedaha geniş bir Endeks aralığına sahiptir. range(x.y)x ve y arasındaki tüm sayıların bir listesini yazdırır
xrange(x,y)döner, xrange(x,y)ancak bir fordöngü kullandıysanız , o zaman xrangedaha hızlıdır. xrangedaha küçük bir Dizin aralığına sahiptir. xrangeyalnızca çıktı almakla xrange(x,y)kalmaz, aynı zamanda içindeki tüm sayıları saklar.
[In] range(1,10)
[Out] [1, 2, 3, 4, 5, 6, 7, 8, 9]
[In] xrange(1,10)
[Out] xrange(1,10)
Bir fordöngü kullanırsanız , o zaman 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 çok fazla bir fark yoktur, ancak sadece yazdırırken bir fark vardır!
range (): range (1, 10), 1'den 10'a kadar bir sayı döndürür ve tüm listeyi bellekte tutar.
xrange (): range () gibi, ancak bir liste döndürmek yerine, isteğe bağlı aralıktaki sayıları üreten bir nesne döndürür. Döngü için bu, range () 'den biraz daha hızlı ve bellekte daha verimlidir. xrange () nesnesini yineleyici gibi kullanır ve talep üzerine sayıları oluşturur.
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
Diğer cevapların bazıları Python 3 2.x 's ortadan söz rangeve 2.x' s adını xrangekadar range. Ancak, 3.0 veya 3.1 (hiç kimsenin olmaması gereken) kullanmıyorsanız, aslında biraz farklı bir tür.
As 3.1 dokümanlar ki:
Aralık nesnelerinin çok az davranışı vardır: yalnızca dizin oluşturma, yineleme ve
lenişlevi destekler.
Bununla birlikte, 3.2+, rangetam bir dizidir - genişletilmiş dilimleri ve a collections.abc.Sequenceile aynı semantiğe sahip tüm yöntemleri destekler list. *
Ve en azından CPython ve PyPy'de (şu anda var olan sadece iki 3.2+ uygulama), indexve countyöntemleri ve inoperatörünün sabit zamanlı uygulamaları da vardır (yalnızca tamsayıları geçtiğiniz sürece). Bu, yazmanın 123456 in r3.2+'de makul olduğu anlamına gelirken, 2.7 veya 3.1'de korkunç bir fikir olurdu.
* 2.6-2.7 ve 3.0-3.1'de issubclass(xrange, collections.Sequence)geri Truedönmesi, 3.2'de düzeltilen ve desteklenmeyen bir hatadır .
Python 2.x içinde
range (x) , bellekte x öğesiyle oluşturulan bir liste döndürür.
>>> a = range(5)
>>> a
[0, 1, 2, 3, 4]
xrange (x) , istek üzerine sayıları üreten bir üretici nesnesi olan bir xrange nesnesi döndürür. for-loop sırasında hesaplanırlar (Tembel Değerlendirme).
Döngü için bu, range () 'den biraz daha hızlı ve bellekte daha verimlidir.
>>> b = xrange(5)
>>> b
xrange(5)
xrange()bir jeneratör değil. xrange(n).__ iter __ () `dir.
(I kullanmalıyım biliyorum bir döngü içinde xrange karşı aralığı test edilirken sürümüyle gelen timeit ama bu hızla basit bir liste anlama örneği kullanılarak bellekten kadar hacklendi) Aşağıdaki bulundu:
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 döngüsünde 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'im düzgün bir şekilde test ediliyor mu? Yavaş xrange örneği hakkında yorumlarınız var mı? Veya daha iyi bir örnek :-)
xrangekadar ve Python 3 ile karşılaştırma artık gereksiz olsa da, biraz daha hızlı görünüyordu.
timeitiçin bu. Birçok kez koşmak, GC'yi devre dışı bırakmak, yerine en iyi saati kullanmak timevb.
python'daki xrange () ve range (), kullanıcıya benzer şekilde çalışır, ancak fark, her iki işlevi kullanarak belleğin nasıl tahsis edildiği hakkında konuştuğumuzda ortaya çıkar.
Range () yöntemini kullanırken, oluşturduğu tüm değişkenler için bellek ayırırız, bu nedenle daha büyük no ile kullanılması önerilmez. oluşturulacak değişkenler.
xrange () ise bir seferde sadece belirli bir değer üretir ve sadece for döngüsüyle birlikte gerekli tüm değerleri yazdırmak için kullanılabilir.
range tüm listeyi oluşturur ve listeyi döndürür. xrange yapmaz - istek üzerine listedeki sayıları üretir.
Ne?
rangeçalışma zamanında statik bir liste döndürür. değerlerin gerektiğinde ve gerektiğinde üretildiği bir (kesinlikle bir tane olmasa da bir jeneratör gibi davranır)
xrangedöndürür object.
Hangisi ne zaman kullanılır?
xrangeÖzellikle bir cep telefonu gibi "belleğe duyarlı bir sisteminiz" olduğunda, 1 milyar gibi devasa bir aralık için bir liste oluşturmak istiyorsanız .rangeListeyi birkaç kez tekrarlamak istiyorsanız kullanın .PS: Python 3.x rangeişlevi == Python 2.x xrangeişlevi.
xrangebir jeneratör nesnesini döndürmez.
Herkes çok iyi açıkladı. Ama kendim görmesini istedim. Python3 kullanıyorum. Bu nedenle, kaynak izleyicisini açtım (Windows'ta!) Ve önce ilk olarak aşağıdaki komutu yürüttüm:
a=0
for i in range(1,100000):
a=a+i
ve sonra 'Kullanımda' bellekteki değişikliği kontrol etti. Önemsizdi. Sonra, aşağıdaki kodu koştu:
for i in list(range(1,100000)):
a=a+i
Anında kullanım için hafızanın büyük bir kısmını aldı. Ve ikna olmuştum. Kendiniz deneyebilirsiniz.
Python 2X kullanıyorsanız, 'range ()' öğesini ilk kodda 'xrange ()' ve 'list (range ())' yerine 'range ()' ile değiştirin.
Yardım belgelerinden.
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 içinde, rangebir liste xrangedöndürür, yinelenebilir bir xrange nesnesi döndürür.
Python 3.x içinde Python 2.x rangeolur xrangeve xrangekaldırılır.
0-N öğelerin taranması / yazdırılması için, aralık ve xrange aşağıdaki gibi çalışır.
range () - bellekte yeni bir liste oluşturur ve tüm 0 ila N öğelerini (tamamen N + 1) alır ve yazdırır. xrange () - öğeleri tarayan ve yalnızca o anda karşılaşılan öğeyi belleğe tutan bir yineleyici örneği oluşturur, bu nedenle her zaman aynı miktarda bellek kullanır.
Gerekli öğenin sadece listenin başında olması durumunda çok fazla zaman ve bellek tasarrufu sağlar.
xrangeyineleyici örneği oluşturmaz. xrangeYinelenebilir, ancak yineleyici olmayan bir nesne yaratır - bir liste gibi neredeyse (ancak tam olarak değil) bir dizi.
Kapsama bir döner listesi ise xrange bir döner xrange , aralık boyutu ne olursa olsun, bu durumda olduğu gibi, tek bir öğe olarak oluşturulur ve aralığı kullanılması durumunda ise yineleme başına kullanılabilir, aynı bellek alır nesne, tüm elemanlar bir kez ve en oluşturulacak bellekte kullanılabilir.
Daha küçük argümanlar için 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
Bu durumda xrange(100)sadece% 20 daha verimlidir.
range: -range, her şeyi aynı anda dolduracaktır.
xrange: -xrange, jeneratör gibi bir şeydir, sayı aralığını istediğinizde resme gelecektir, ancak loop.so için bellek kullanmak istediğinizde olduğu gibi saklanmasını istemezsiniz.
range() Python'da 2.x
Bu işlev aslında range()Python'da bulunan eski bir işlevdir 2.xve birlist ve belirtilen aralıktaki öğeleri içeren nesnenin .
Ancak, bir dizi sayı içeren bir listeyi başlatmak söz konusu olduğunda bu uygulama çok verimsizdir. Örneğin, for i in range(1000000)bu listenin belleğe kaydedilmesini gerektirdiğinden, hem bellek hem de zaman kullanımı açısından yürütülmesi çok pahalı bir komut olacaktır.
range()Python 3.xve xrange()Python'da2.x
Python 3.xdaha yeni bir uygulamasına başladık range()yeni uygulama Python zaten mevcut iken ( 2.xaracılığıylaxrange() işlev ).
range()Olarak bir stratejiyi kullanan yavaş değerlendirme. Aralıktaki öğelerin büyük bir listesini oluşturmak yerine, yeni uygulama sınıfı range, belirli bir aralıkta gerekli öğeleri temsil eden hafif bir nesne olan sınıfı açık bir şekilde bellekte saklamadan sunar (bu, jeneratörler gibi gelebilir, ancak tembel değerlendirme kavramı farklı).
Örnek olarak aşağıdakileri göz önünde bulundurun:
# Python 2.x
>>> a = range(10)
>>> type(a)
<type 'list'>
>>> b = xrange(10)
>>> type(b)
<type 'xrange'>
ve
# Python 3.x
>>> a = range(10)
>>> type(a)
<class 'range'>
Bu gönderiye bakın aralığı ve xrange arasındaki farkı bulmak için:
Alıntılamak:
rangetam olarak düşündüğünüzü döndürür: 0 ile başlayan tanımlanmış bir uzunluktaki ardışık tamsayıların bir listesixrange, ancak, bir yineleyici gibi büyük ölçüde hareket eden bir "xrange nesnesi" döndürür
xrangebir yineleyici değildir. Tarafından döndürülen liste rangeyinelemeyi destekliyor (bir liste hemen hemen yinelenebilir bir prototip örneğidir). Toplam faydası xrange"minimal" değildir. Ve bunun gibi.