Yanıtlar:
Python 2.x'te:
range
bir 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, range
python'lara eşdeğerdir xrange
ve listeyi almak için kullanmanız gerekir list(range(...))
.
xrange(x).__iter__()
bir jeneratördür.
i
baş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 .
xrange
Bir 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, timeit
hangi 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 seconds
ona bakmanın doğru yolu değil, (90.5-51.1)/51.1 = 1.771 times slower
doğ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.
xrange
sadece 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 range
ve bunun 2.x gibi davrandığını, xrange
ancak 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.
xrange
yok değil bir yineleyici döndürür.
and only keeps one number in memory at a time
ve 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()
, ancakxrange
liste 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 xrange
aşı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 xrange
bir jeneratördür ve sadece ihtiyaca göre sayılar üretir, yani yineleme devam ederse.
Python-3'te, range
işlevselliğin uygulanması xrange
Python-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 for
döngü kullanırsanız x ile y arasındaki her sayının bir listesini döndürür , o range
zaman yavaştır. Aslında, range
daha 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 for
döngü kullandıysanız , o zaman xrange
daha hızlıdır. xrange
daha küçük bir Dizin aralığına sahiptir. xrange
yalnı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 for
dö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 range
ve 2.x' s adını xrange
kadar 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
len
işlevi destekler.
Bununla birlikte, 3.2+, range
tam bir dizidir - genişletilmiş dilimleri ve a collections.abc.Sequence
ile 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), index
ve count
yöntemleri ve in
operatörünün sabit zamanlı uygulamaları da vardır (yalnızca tamsayıları geçtiğiniz sürece). Bu, yazmanın 123456 in r
3.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 True
dö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 :-)
xrange
kadar ve Python 3 ile karşılaştırma artık gereksiz olsa da, biraz daha hızlı görünüyordu.
timeit
için bu. Birçok kez koşmak, GC'yi devre dışı bırakmak, yerine en iyi saati kullanmak time
vb.
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)
xrange
dö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 .range
Listeyi birkaç kez tekrarlamak istiyorsanız kullanın .PS: Python 3.x range
işlevi == Python 2.x xrange
işlevi.
xrange
bir 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, range
bir liste xrange
döndürür, yinelenebilir bir xrange nesnesi döndürür.
Python 3.x içinde Python 2.x range
olur xrange
ve xrange
kaldı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.
xrange
yineleyici örneği oluşturmaz. xrange
Yinelenebilir, 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.x
ve 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.x
ve xrange()
Python'da2.x
Python 3.x
daha yeni bir uygulamasına başladık range()
yeni uygulama Python zaten mevcut iken ( 2.x
aracı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:
range
tam 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
xrange
bir yineleyici değildir. Tarafından döndürülen liste range
yinelemeyi destekliyor (bir liste hemen hemen yinelenebilir bir prototip örneğidir). Toplam faydası xrange
"minimal" değildir. Ve bunun gibi.