Jawaban:
Dengan Python 2.x:
range
membuat daftar, jadi jika Anda melakukannya range(1, 10000000)
, buat daftar di memori dengan 9999999
elemen.
xrange
adalah objek urutan yang mengevaluasi malas.
Dalam Python 3, range
apakah setara dengan python xrange
, dan untuk mendapatkan daftar, Anda harus menggunakan list(range(...))
.
xrange(x).__iter__()
adalah generator.
i
dievaluasi berdasarkan permintaan daripada inisialisasi.
range membuat daftar, jadi jika Anda melakukannya
range(1, 10000000)
, buat daftar di memori dengan9999999
elemen.
xrange
adalah generator, sehinggamerupakan objek urutanadalahyang mengevaluasi malas.
Ini benar, tetapi dalam Python 3, .range()
akan dilaksanakan oleh Python 2 .xrange()
. Jika Anda benar-benar perlu membuat daftar, Anda harus melakukan:
list(range(1,100))
xrange
generator? Ini adalah fungsi yang berisi yield
pernyataan, dan menurut glosarium fungsi-fungsi tersebut disebut generator.
Ingat, gunakan timeit
modul untuk menguji potongan kode kecil mana yang lebih cepat!
$ 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
Secara pribadi, saya selalu menggunakan .range()
, kecuali aku berhadapan dengan benar daftar besar - seperti yang Anda lihat, waktu-bijaksana, untuk daftar satu juta entri, overhead ekstra hanya 0,04 detik. Dan seperti yang ditunjukkan Corey, dalam Python 3.0 .xrange()
akan hilang dan .range()
akan memberi Anda perilaku iterator yang bagus.
python -m timeit "for i in xrange(1000000):" " pass"
the extra overhead is only 0.04 seconds
bukankah cara yang tepat untuk melihatnya, (90.5-51.1)/51.1 = 1.771 times slower
benar karena menyampaikan bahwa jika ini adalah inti dari program Anda, berpotensi dapat menghambatnya. Namun, jika ini adalah bagian kecil maka 1,77x tidak terlalu banyak.
xrange
hanya menyimpan rentang params dan menghasilkan angka sesuai permintaan. Namun implementasi C dari Python saat ini membatasi argumennya ke C rindu:
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]
Perhatikan bahwa dalam Python 3.0 hanya ada range
dan berperilaku seperti 2.x xrange
tetapi tanpa batasan pada titik akhir minimum dan maksimum.
xrange mengembalikan iterator dan hanya menyimpan satu nomor dalam memori pada satu waktu. Kisaran menyimpan seluruh daftar nomor dalam memori.
xrange
tidak tidak mengembalikan iterator.
and only keeps one number in memory at a time
dan di mana sisanya ditempatkan tolong bimbing saya ..
Luangkan waktu dengan Referensi Perpustakaan . Semakin Anda terbiasa dengannya, semakin cepat Anda dapat menemukan jawaban untuk pertanyaan seperti ini. Terutama penting adalah beberapa bab pertama tentang objek dan tipe builtin.
Keuntungan dari tipe xrange adalah bahwa objek xrange akan selalu mengambil jumlah memori yang sama, tidak peduli ukuran rentang yang diwakilinya. Tidak ada keunggulan kinerja yang konsisten.
Cara lain untuk menemukan informasi cepat tentang konstruksi Python adalah docstring dan fungsi bantu:
print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)
Saya terkejut tidak ada yang membaca dokumen :
Fungsi ini sangat mirip dengan
range()
, tetapi mengembalikanxrange
objek, bukan daftar. Ini adalah jenis urutan buram yang menghasilkan nilai yang sama dengan daftar yang sesuai, tanpa benar-benar menyimpan semuanya secara bersamaan. Keuntunganxrange()
lebihrange()
adalah minimal (karenaxrange()
masih harus membuat nilai ketika diminta) kecuali jika rentang yang sangat besar digunakan pada mesin yang kekurangan memori atau ketika semua elemen rentang tidak pernah digunakan (seperti ketika loop adalah biasanya diakhiri denganbreak
).
range membuat daftar, jadi jika Anda melakukan range (1, 10000000) itu membuat daftar di memori dengan 10000000 elemen. xrange adalah generator, jadi ia mengevaluasi dengan malas.
Ini memberi Anda dua keuntungan:
MemoryError
.Anda akan menemukan keuntungan xrange
lebih dari range
contoh sederhana ini:
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
Contoh di atas tidak mencerminkan sesuatu yang jauh lebih baik jika terjadi xrange
.
Sekarang lihat kasus berikut di mana range
benar-benar sangat lambat, dibandingkan dengan 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
Dengan range
, ia sudah membuat daftar dari 0 hingga 10.000.000 (memakan waktu), tetapi xrange
merupakan generator dan hanya menghasilkan angka berdasarkan kebutuhan, yaitu, jika iterasi berlanjut.
Dalam Python-3, implementasi range
fungsionalitasnya sama seperti xrange
pada Python-2, sementara mereka telah dihilangkan dengan xrange
Python-3
Selamat Coding !!
Ini untuk alasan optimasi.
range () akan membuat daftar nilai dari awal hingga akhir (0 .. 20 dalam contoh Anda). Ini akan menjadi operasi yang mahal pada rentang yang sangat besar.
xrange () di sisi lain jauh lebih optimal. itu hanya akan menghitung nilai berikutnya ketika dibutuhkan (melalui objek urutan xrange) dan tidak membuat daftar semua nilai seperti rentang () tidak.
range(x,y)
mengembalikan daftar setiap angka di antara x dan y jika Anda menggunakan for
loop, maka range
lebih lambat. Bahkan, range
memiliki rentang Indeks yang lebih besar. range(x.y)
akan mencetak daftar semua angka di antara x dan y
xrange(x,y)
kembali xrange(x,y)
tetapi jika Anda menggunakan for
loop, maka xrange
lebih cepat. xrange
memiliki rentang Indeks yang lebih kecil. xrange
tidak hanya akan mencetak xrange(x,y)
tetapi masih akan menyimpan semua nomor yang ada di dalamnya.
[In] range(1,10)
[Out] [1, 2, 3, 4, 5, 6, 7, 8, 9]
[In] xrange(1,10)
[Out] xrange(1,10)
Jika Anda menggunakan for
loop, maka itu akan berhasil
[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
Tidak ada banyak perbedaan saat menggunakan loop, meskipun ada perbedaan ketika hanya mencetaknya!
range (): range (1, 10) mengembalikan daftar dari 1 hingga 10 angka & menahan seluruh daftar dalam memori.
xrange (): Seperti rentang (), tetapi alih-alih mengembalikan daftar, kembalikan objek yang menghasilkan angka dalam rentang berdasarkan permintaan. Untuk perulangan, ini sedikit lebih cepat daripada range () dan memori lebih efisien. objek xrange () seperti iterator dan menghasilkan angka sesuai permintaan. (Evaluasi Malas)
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
Beberapa jawaban lain menyebutkan bahwa Python 3 menghilangkan 2.x's range
dan mengganti nama 2.x's xrange
menjadirange
. Namun, kecuali Anda menggunakan 3.0 atau 3.1 (yang seharusnya tidak ada), sebenarnya jenisnya agak berbeda.
Seperti yang dikatakan dalam dokumen 3.1 :
Objek jangkauan memiliki perilaku yang sangat sedikit: mereka hanya mendukung pengindeksan, iterasi, dan
len
fungsi.
Namun, dalam 3.2+, range
adalah urutan lengkap — ia mendukung irisan yang diperluas, dan semua metode collections.abc.Sequence
dengan semantik yang sama dengan a list
. *
Dan, setidaknya dalam CPython dan PyPy (hanya dua 3.2+ implementasi yang saat ini ada), juga memiliki implementasi konstan-waktu index
dan count
metode dan in
operator (selama Anda hanya lulus bilangan bulat). Ini berarti menulis 123456 in r
masuk akal dalam 3,2+, sedangkan dalam 2,7 atau 3,1 itu akan menjadi ide yang mengerikan.
* Fakta yang issubclass(xrange, collections.Sequence)
kembali True
di 2.6-2.7 dan 3.0-3.1 adalah bug yang diperbaiki di 3.2 dan tidak di-backport.
Dalam python 2.x
range (x) mengembalikan daftar, yang dibuat dalam memori dengan x elemen.
>>> a = range(5)
>>> a
[0, 1, 2, 3, 4]
xrange (x) mengembalikan objek xrange yang merupakan objek generator yang menghasilkan angka sesuai permintaan. mereka dihitung selama for-loop (Evaluasi Malas).
Untuk perulangan, ini sedikit lebih cepat dari range () dan lebih hemat memori.
>>> b = xrange(5)
>>> b
xrange(5)
xrange()
bukan generator. xrange(n)
.__ iter __ () `adalah.
Saat menguji rentang terhadap xrange dalam satu lingkaran (saya tahu saya harus menggunakan timeit , tapi ini dengan cepat diretas dari memori menggunakan contoh pemahaman daftar sederhana) Saya menemukan yang berikut:
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)
pemberian yang mana:
$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?
Atau, menggunakan xrange dalam for loop:
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
Apakah cuplikan saya pengujian dengan benar? Adakah komentar tentang instance xrange yang lebih lambat? Atau contoh yang lebih baik :-)
xrange
tampak sedikit lebih cepat, meskipun dengan Python 3 perbandingannya sekarang mubazir.
timeit
. Ini mengurus menjalankan berkali-kali, menonaktifkan GC, menggunakan jam terbaik alih-alih time
, dll.
xrange () dan range () dalam python bekerja sama seperti untuk pengguna, tetapi perbedaannya muncul ketika kita berbicara tentang bagaimana memori dialokasikan dalam menggunakan kedua fungsi.
Saat kami menggunakan rentang () kami mengalokasikan memori untuk semua variabel yang dihasilkannya, jadi tidak disarankan untuk digunakan dengan no yang lebih besar. variabel yang akan dihasilkan.
xrange () di sisi lain hanya menghasilkan nilai tertentu pada suatu waktu dan hanya dapat digunakan dengan loop for untuk mencetak semua nilai yang diperlukan.
range menghasilkan seluruh daftar dan mengembalikannya. xrange tidak - ia menghasilkan angka dalam daftar sesuai permintaan.
Apa?
range
mengembalikan daftar statis saat runtime.
xrange
mengembalikan sebuahobject
(yang bertindak seperti generator, meskipun jelas bukan salah satu) dari mana nilai-nilai dihasilkan saat dan ketika diperlukan.
Kapan menggunakan yang mana?
xrange
jika Anda ingin membuat daftar untuk rentang raksasa, katakan 1 miliar, terutama ketika Anda memiliki "sistem yang peka terhadap memori" seperti ponsel.range
jika Anda ingin mengulangi daftar beberapa kali.PS: Python 3.x ini range
fungsi == Python 2.x ini xrange
fungsi.
xrange
tidak mengembalikan objek generator.
Semua orang telah menjelaskannya dengan sangat. Tapi saya ingin melihatnya sendiri. Saya menggunakan python3. Jadi, saya membuka monitor sumber daya (di Windows!), Dan pertama, jalankan perintah berikut terlebih dahulu:
a=0
for i in range(1,100000):
a=a+i
dan kemudian memeriksa perubahan dalam memori 'In Use'. Itu tidak signifikan. Kemudian, saya menjalankan kode berikut:
for i in list(range(1,100000)):
a=a+i
Dan butuh sebagian besar memori untuk digunakan, secara instan. Dan saya yakin. Anda bisa mencobanya sendiri.
Jika Anda menggunakan Python 2X, ganti 'range ()' dengan 'xrange ()' di kode pertama dan 'list (range ())' dengan 'range ()'.
Dari dokumen bantuan.
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
Perbedaannya jelas. Dalam Python 2.x, range
mengembalikan daftar, xrange
mengembalikan objek xrange yang dapat diubah.
Dalam Python 3.x, range
menjadi xrange
dari Python 2.x, dan xrange
dihapus.
Pada persyaratan untuk memindai / mencetak item 0-N, range dan xrange berfungsi sebagai berikut.
range () - membuat daftar baru dalam memori dan mengambil seluruh item 0 hingga N (total N +1) dan mencetaknya. xrange () - membuat instance iterator yang memindai item dan hanya menyimpan item yang ada saat ini ke dalam memori, sehingga menggunakan jumlah memori yang sama sepanjang waktu.
Dalam hal elemen yang diperlukan agak di awal daftar hanya kemudian menghemat banyak waktu dan memori.
xrange
tidak membuat instance iterator. Ia menciptakan sebuah xrange
objek, yang bisa diubah, tetapi bukan iterator — hampir (tetapi tidak cukup) berurutan, seperti daftar.
Rentang mengembalikan daftar sementara xrange mengembalikan objek xrange yang mengambil memori yang sama terlepas dari ukuran rentang, seperti dalam kasus ini, hanya satu elemen yang dihasilkan dan tersedia per iterasi sedangkan dalam hal menggunakan rentang, semua elemen dihasilkan sekaligus dan tersedia di memori.
Perbedaannya berkurang untuk argumen yang lebih kecil ke 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
Dalam hal xrange(100)
ini hanya sekitar 20% lebih efisien.
range: -range akan mengisi semuanya sekaligus. Yang artinya setiap angka dari rentang akan menempati memori.
xrange: -xrange adalah sesuatu seperti generator, itu akan muncul dalam gambar ketika Anda ingin kisaran angka tetapi Anda tidak ingin mereka disimpan, seperti ketika Anda ingin menggunakannya untuk loop.so memori yang efisien.
range()
dalam Python 2.x
Fungsi ini pada dasarnya adalah fungsi lama range()
yang tersedia dalam Python 2.x
dan mengembalikan sebuah instance dari list
objek yang berisi elemen-elemen dalam rentang yang ditentukan.
Namun, implementasi ini terlalu tidak efisien ketika harus menginisialisasi daftar dengan sejumlah angka. Misalnya, for i in range(1000000)
akan menjadi perintah yang sangat mahal untuk dieksekusi, baik dari segi memori dan penggunaan waktu karena memerlukan penyimpanan daftar ini ke dalam memori.
range()
dalam Python 3.x
dan xrange()
Python2.x
Python 3.x
memperkenalkan implementasi yang lebih baru dari range()
(sementara implementasi yang lebih baru sudah tersedia di Python 2.x
melaluixrange()
fungsi).
The range()
memanfaatkan strategi yang dikenal sebagai evaluasi malas. Alih-alih membuat daftar besar elemen dalam jangkauan, implementasi yang lebih baru memperkenalkan kelas range
, objek ringan yang mewakili elemen yang diperlukan dalam rentang yang diberikan, tanpa menyimpannya secara eksplisit dalam memori (ini mungkin terdengar seperti generator tetapi konsep evaluasi malas adalah berbeda).
Sebagai contoh, pertimbangkan hal berikut:
# Python 2.x
>>> a = range(10)
>>> type(a)
<type 'list'>
>>> b = xrange(10)
>>> type(b)
<type 'xrange'>
dan
# Python 3.x
>>> a = range(10)
>>> type(a)
<class 'range'>
Lihat posting ini untuk menemukan perbedaan antara rentang dan xrange:
Kutipan:
range
mengembalikan persis apa yang Anda pikirkan: daftar bilangan bulat berurutan, dengan panjang yang ditentukan dimulai dengan 0.xrange
, namun, mengembalikan "objek xrange" , yang berfungsi sangat mirip dengan iterator
xrange
bukan iterator. Daftar dikembalikan oleh range
apakah mendukung iterasi (daftar cukup banyak contoh prototip dari iterable). Manfaat keseluruhan xrange
tidak "minimal". Dan seterusnya.