Sự khác biệt giữa các hàm phạm vi và xrange trong Python 2.X là gì?


719

Rõ ràng xrange nhanh hơn nhưng tôi không biết tại sao nó lại nhanh hơn (và không có bằng chứng nào ngoài giai thoại cho đến nay là nhanh hơn) hay ngoài những điều đó thì khác

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

Câu trả lời:


817

Trong Python 2.x:

  • rangetạo một danh sách, vì vậy nếu bạn làm range(1, 10000000)nó sẽ tạo một danh sách trong bộ nhớ với 9999999các phần tử.

  • xrange là một đối tượng trình tự đánh giá một cách lười biếng.

Trong Python 3, rangetương đương với python xrange, và để có được danh sách, bạn phải sử dụng list(range(...)).


65
xrange là nto chính xác là một trình tạo nhưng nó đánh giá một cách lười biếng và hoạt động như một trình tạo.
Vaibhav Mishra

47
xrange(x).__iter__()là một máy phát điện.
augustomen

34
Tại sao họ làm xrange, thay vì làm cho phạm vi lười biếng?
Rob Grant

22
@RobertGrant, họ đã làm. Trong Python 3. (Họ không thể làm điều đó trong dòng Python 2.x, vì tất cả các thay đổi phải tương thích ngược.)
Paul Draper

12
@Ratul có nghĩa là mỗi cái iđược đánh giá theo yêu cầu thay vì khởi tạo.
Onilol

223

phạm vi tạo một danh sách, vì vậy nếu bạn làm range(1, 10000000)nó sẽ tạo một danh sách trong bộ nhớ với 9999999các phần tử.

xrange là một trình tạo, vì vậy nó là một đối tượng trình tự được đánh giá một cách lười biếng.

Điều này đúng, nhưng trong Python 3, .range()sẽ được Python 2 triển khai .xrange(). Nếu bạn cần thực sự tạo danh sách, bạn sẽ cần phải làm:

list(range(1,100))

3
Tôi không thấy rằng đó là một vấn đề lớn (liên quan đến việc phá vỡ các ứng dụng hiện có) vì phạm vi chủ yếu là để tạo các chỉ mục được sử dụng cho các vòng lặp như "cho tôi trong phạm vi (1, 10):"
Benjamin Autin

10
+1 Cảm ơn câu trả lời này, thông tin về phạm vi thay thế Python 3 bằng xrange rất hữu ích. Tôi thực sự đã nói với ai đó sử dụng xrange thay thế hoặc phạm vi và họ nói rằng nó không quan trọng trong python 3, vì vậy tôi đã tìm kiếm thêm thông tin và câu trả lời này đã xuất hiện :)
Cervo

Có gì sai khi gọi xrangemột máy phát điện? Nó là một hàm chứa yieldcâu lệnh và theo thuật ngữ các hàm như vậy được gọi là các trình tạo.
ánh sáng mùa đông

@winterlight, hãy nghĩ thuật ngữ chính xác cho nó là iterator. Máy phát điện cũng có thể nhận được.
McSinyx

112

Hãy nhớ rằng, sử dụng timeitmô-đun để kiểm tra đoạn mã nhỏ nào nhanh hơ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

Cá nhân, tôi luôn sử dụng .range(), trừ khi tôi đang xử lý các danh sách thực sự lớn - như bạn có thể thấy, theo thời gian, đối với danh sách một triệu mục, chi phí phụ chỉ là 0,04 giây. Và như Corey chỉ ra, trong Python 3.0 .xrange()sẽ biến mất và .range()sẽ cung cấp cho bạn hành vi lặp tốt đẹp.


12
+1 cho ví dụ về thời gian. Lưu ý: để chạy trong windows cmd, cần phải sử dụng dấu ngoặc kép, tức là ". Vì vậy, mã sẽ làpython -m timeit "for i in xrange(1000000):" " pass"
stalk

10
Lợi ích chính của xrange là bộ nhớ, không phải thời gian.
endolith

3
+1 cho câu trả lời thực tế: sử dụng phạm vi trừ khi rất lớn . BTW họ giống hệt nhau về mặt khái niệm, đúng không? Kì lạ là không có câu trả lời nào.
Bob Stein

6
Nếu xrange nhanh hơn và không có bộ nhớ hog, tại sao lại sử dụng phạm vi?
Austin Mohr

8
Tôi đồng ý với tuyên bố của bạn nói chung, nhưng đánh giá của bạn là sai: the extra overhead is only 0.04 secondskhông phải là cách chính xác để xem xét nó, (90.5-51.1)/51.1 = 1.771 times slowerlà chính xác bởi vì nó cho rằng nếu đây là vòng lặp cốt lõi của chương trình của bạn thì nó có thể gây tắc nghẽn cho nó. Tuy nhiên, nếu đây là một phần nhỏ thì 1,77x không nhiều.
chacham15

65

xrangechỉ lưu trữ các thông số phạm vi và tạo ra các số theo yêu cầu. Tuy nhiên, việc triển khai C của Python hiện hạn chế các đối số của nó đối với C từ lâu:

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]

Lưu ý rằng trong Python 3.0 chỉ có rangevà nó hoạt động như 2.x xrangenhưng không có giới hạn về điểm cuối tối thiểu và tối đa.


39

xrange trả về một iterator và chỉ giữ một số trong bộ nhớ tại một thời điểm. phạm vi giữ toàn bộ danh sách các số trong bộ nhớ.


9
xrangekhông không trả về một iterator.
abarnert

and only keeps one number in memory at a timevà nơi đặt phần còn lại xin vui lòng hướng dẫn cho tôi ..
SIslam

5
@SIslam Nếu nó biết bắt đầu, kết thúc và hiện tại, nó có thể tính toán tiếp theo, từng cái một.
Justin Meiners

30

Hãy dành một chút thời gian với Thư viện tham khảo . Bạn càng quen thuộc với nó, bạn càng có thể nhanh chóng tìm thấy câu trả lời cho các câu hỏi như thế này. Đặc biệt quan trọng là một vài chương đầu tiên về các đối tượng và kiểu dựng sẵn.

Ưu điểm của loại xrange là một đối tượng xrange sẽ luôn chiếm cùng một lượng bộ nhớ, bất kể kích thước của phạm vi mà nó đại diện. Không có lợi thế hiệu suất phù hợp.

Một cách khác để tìm thông tin nhanh về cấu trúc Python là chuỗi doc và hàm trợ giúp:

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

1
Thư viện rất tốt nhưng không phải lúc nào cũng dễ dàng có được câu trả lời cho câu hỏi bạn có.
Teifion

2
Đi đến tham chiếu thư viện, nhấn ctrl + f, tìm kiếm phạm vi và bạn sẽ nhận được hai kết quả. Không có nhiều nỗ lực để tìm câu trả lời cho câu hỏi này.
David Locke

1
Tài liệu tham khảo thư viện không hoạt động. Bạn có thể vui lòng cập nhật nó?
mk ..

14

Tôi bị sốc không ai đọc tài liệu :

Hàm này rất giống với range(), nhưng trả về một xrangeđối tượng thay vì danh sách. Đây là một loại chuỗi mờ mang lại các giá trị tương tự như danh sách tương ứng, mà không thực sự lưu trữ tất cả chúng cùng một lúc. Lợi thế của xrange()hơn range()là tối thiểu (vì xrange()vẫn phải tạo các giá trị khi được yêu cầu) trừ khi sử dụng phạm vi rất lớn trên máy bị thiếu bộ nhớ hoặc khi tất cả các thành phần của phạm vi không bao giờ được sử dụng (chẳng hạn như khi vòng lặp là thường chấm dứt với break).


13

phạm vi tạo một danh sách, vì vậy nếu bạn thực hiện phạm vi (1, 10000000), nó sẽ tạo một danh sách trong bộ nhớ với 10000000 phần tử. xrange là một trình tạo, vì vậy nó đánh giá một cách lười biếng.

Điều này mang lại cho bạn hai lợi thế:

  1. Bạn có thể lặp lại danh sách dài hơn mà không nhận được a MemoryError.
  2. Vì nó giải quyết từng số một cách lười biếng, nếu bạn dừng lặp lại sớm, bạn sẽ không lãng phí thời gian để tạo toàn bộ danh sách.

12

Bạn sẽ tìm thấy lợi thế xrangehơn rangetrong ví dụ đơn giản này:

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

Ví dụ trên không phản ánh bất cứ điều gì tốt hơn đáng kể trong trường hợp xrange.

Bây giờ hãy nhìn vào trường hợp sau đây, nơi rangethực sự rất chậm, so với 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

Với range, nó đã tạo một danh sách từ 0 đến 100000000 (tốn thời gian), nhưng xrangelà một trình tạo và nó chỉ tạo ra các số dựa trên nhu cầu, nghĩa là, nếu việc lặp lại tiếp tục.

Trong Python-3, việc triển khai rangechức năng giống như xrangetrong Python-2, trong khi chúng đã loại bỏ xrangetrong Python-3

Chúc mừng mã hóa !!


11

Đó là vì lý do tối ưu hóa.

phạm vi () sẽ tạo danh sách các giá trị từ đầu đến cuối (0 .. 20 trong ví dụ của bạn). Điều này sẽ trở thành một hoạt động đắt tiền trên phạm vi rất lớn.

xrange () mặt khác được tối ưu hóa hơn nhiều. nó sẽ chỉ tính giá trị tiếp theo khi cần (thông qua một đối tượng chuỗi xrange) và không tạo danh sách tất cả các giá trị như phạm vi ().


9

range(x,y)trả về một danh sách của mỗi số ở giữa x và y nếu bạn sử dụng một forvòng lặp, thì rangechậm hơn. Trong thực tế, rangecó một phạm vi Index lớn hơn. range(x.y)sẽ in ra một danh sách tất cả các số ở giữa x và y

xrange(x,y)trả về xrange(x,y)nhưng nếu bạn đã sử dụng một forvòng lặp, thì xrangenhanh hơn. xrangecó phạm vi Index nhỏ hơn. xrangesẽ không chỉ in ra xrange(x,y)mà còn giữ được tất cả các số có trong đó.

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

Nếu bạn sử dụng một forvòng lặp, thì nó sẽ hoạt động

[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

Không có nhiều sự khác biệt khi sử dụng các vòng lặp, mặc dù có một sự khác biệt khi chỉ in nó!


8

phạm vi (): phạm vi (1, 10) trả về danh sách từ 1 đến 10 số và giữ toàn bộ danh sách trong bộ nhớ.

xrange (): Giống như phạm vi (), nhưng thay vì trả về danh sách, trả về một đối tượng tạo ra các số trong phạm vi theo yêu cầu. Đối với vòng lặp, tốc độ này nhanh hơn phạm vi () và hiệu quả bộ nhớ cao hơn. đối tượng xrange () giống như một trình vòng lặp và tạo ra các số theo yêu cầu. (Đánh giá lười biếng)

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

6

Một số câu trả lời khác đề cập rằng Python 3 đã loại bỏ 2.x rangevà đổi tên thành 2.x xrangethành range. Tuy nhiên, trừ khi bạn đang sử dụng 3.0 hoặc 3.1 (mà không ai nên làm), thực tế nó là một loại hơi khác.

Như các tài liệu 3.1 nói:

Các đối tượng phạm vi có rất ít hành vi: chúng chỉ hỗ trợ lập chỉ mục, lặp và lenhàm.

Tuy nhiên, trong 3.2+, rangelà một chuỗi đầy đủ, nó hỗ trợ các lát cắt mở rộng và tất cả các phương thức collections.abc.Sequencecó cùng ngữ nghĩa như a list. *

Và, ít nhất là trong CPython và PyPy (hai triển khai 3.2+ duy nhất hiện có), nó cũng có các triển khai indexcountphương thức và intoán tử liên tục theo thời gian (miễn là bạn chỉ truyền cho nó số nguyên). Điều này có nghĩa là viết 123456 in rlà hợp lý trong 3.2+, trong khi ở 2.7 hoặc 3.1 thì đó là một ý tưởng khủng khiếp.


* Thực tế là issubclass(xrange, collections.Sequence)trả về Truetrong 2.6-2.7 và 3.0-3.1 là một lỗi đã được sửa trong 3.2 và không được nhập.


6

Trong trăn 2.x

phạm vi (x) trả về một danh sách, được tạo trong bộ nhớ với các phần tử x.

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

xrange (x) trả về một đối tượng xrange là một trình tạo obj tạo ra các số theo yêu cầu. chúng được tính toán trong vòng lặp for (Đánh giá lười biếng).

Đối với vòng lặp, tốc độ này nhanh hơn một chút so với phạm vi () và hiệu quả bộ nhớ cao hơn.

>>> b = xrange(5)
>>> b
xrange(5)

xrange()không phải là một máy phát điện. xrange(n).__ iter __ () `là.
th3an0maly

5

Khi kiểm tra phạm vi chống xrange trong một vòng lặp (tôi biết tôi nên sử dụng timeit , nhưng điều này đã nhanh chóng bị hack từ bộ nhớ bằng cách sử dụng một ví dụ hiểu danh sách đơn giản) Tôi đã tìm thấy như sau:

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)

cung cấp cho:

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

Hoặc, sử dụng xrange trong vòng lặp 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

Kiểm tra đoạn mã của tôi có đúng không? Bất kỳ ý kiến ​​về trường hợp chậm hơn của xrange? Hoặc một ví dụ tốt hơn :-)


2
Chạy một điểm chuẩn như thế này, một lần, không cung cấp kết quả thời gian chính xác. Luôn luôn có một phương sai .. Nó có thể là GC hoặc một quá trình khác đánh cắp CPU ... bất cứ điều gì. Đó là lý do tại sao điểm chuẩn thường chạy 10-100-1000 -...
Vajk Hermecz

đây chỉ là một bản in đoạn trích vội vàng - tôi đã chạy nó một vài lần, nhưng chỉ lên tới khoảng 100, và xrangecó vẻ hơi nhanh hơn, mặc dù với Python 3, sự so sánh hiện đang dư thừa.
Dave Everitt

3
Đây là những gì timeitdành cho. Nó đảm nhiệm việc chạy nhiều lần, vô hiệu hóa GC, sử dụng đồng hồ tốt nhất thay vì time, v.v.
abarnert

4

xrange () và phạm vi () trong python hoạt động tương tự như đối với người dùng, nhưng sự khác biệt xuất hiện khi chúng ta đang nói về cách bộ nhớ được phân bổ trong việc sử dụng cả hai hàm.

Khi chúng tôi đang sử dụng phạm vi (), chúng tôi phân bổ bộ nhớ cho tất cả các biến mà nó đang tạo, do đó không nên sử dụng với số lớn hơn. các biến được tạo.

mặt khác, xrange () chỉ tạo ra một giá trị cụ thể và chỉ có thể được sử dụng với vòng lặp for để in tất cả các giá trị cần thiết.


3

phạm vi tạo ra toàn bộ danh sách và trả về nó. xrange không - nó tạo ra các số trong danh sách theo yêu cầu.


2

xrange sử dụng một trình vòng lặp (tạo các giá trị khi đang bay), phạm vi trả về một danh sách.


2

Gì?
rangetrả về một danh sách tĩnh khi chạy.
xrangetrả lại mộtobject (hoạt động như một trình tạo, mặc dù nó chắc chắn không phải là một) từ đó các giá trị được tạo khi và khi được yêu cầu.

Khi nào nên sử dụng?

  • Sử dụng xrange nếu bạn muốn tạo một danh sách cho một phạm vi khổng lồ, giả sử là 1 tỷ, đặc biệt là khi bạn có một "hệ thống nhạy cảm với bộ nhớ" như điện thoại di động.
  • Sử dụng rangenếu bạn muốn lặp lại danh sách nhiều lần.

PS: Python 3.x của rangechức năng == Python 2.x của xrangechức năng.


xrangekhông trả về một đối tượng máy phát.
abarnert

Nếu tôi hiểu chính xác, đó là cách giải thích ở đây (đối với Python 2.x): wiki.python.org/moin/Generators
kmario23

Sau đó, wiki là sai. (Tôi không biết "SH" là ai đã thêm và ký nhận xét đó.) Tài liệu chính thức là đúng; bạn có thể tự kiểm tra và xem đó là trình tạo hay trình tự.
abarnert

đồng ý. Nhưng nó vẫn còn khó hiểu sau khi đọc nó: stackoverflow.com/questions/135041/
triệt

1
Câu hỏi thú vị là phải làm gì khi người phiên dịch không đồng ý với các tài liệu chính thức, hoặc với một người phiên dịch khác, nhưng may mắn thay, điều đó không xuất hiện quá thường xuyên
Abarnert

2

Mọi người đã giải thích nó rất nhiều. Nhưng tôi muốn nó nhìn thấy nó cho chính mình. Tôi sử dụng python3. Vì vậy, tôi đã mở trình giám sát tài nguyên (trong Windows!) Và trước tiên, thực hiện lệnh sau trước:

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

và sau đó kiểm tra thay đổi trong bộ nhớ 'Đang sử dụng'. Nó không đáng kể. Sau đó, tôi chạy đoạn mã sau:

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

Và nó đã chiếm một phần lớn bộ nhớ để sử dụng, ngay lập tức. Và, tôi đã bị thuyết phục. Bạn có thể thử nó cho chính mình.

Nếu bạn đang sử dụng Python 2X, sau đó thay thế 'phạm vi ()' bằng 'xrange ()' trong mã đầu tiên và 'list (phạm vi ())' bằng 'phạm vi ()'.


2

Từ các tài liệu trợ giúp.

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

Sự khác biệt là rõ ràng. Trong Python 2.x, rangetrả về một danh sách, xrangetrả về một đối tượng xrange có thể lặp lại.

Trong Python 3.x, rangetrở thành xrangePython 2.x và xrangebị xóa.


1

Theo yêu cầu quét / in các mục 0-N, phạm vi và xrange hoạt động như sau.

phạm vi () - tạo một danh sách mới trong bộ nhớ và lấy toàn bộ 0 đến N mục (hoàn toàn là N + 1) và in chúng. xrange () - tạo một cá thể iterator quét qua các mục và chỉ giữ các mục gặp phải hiện tại vào bộ nhớ, do đó sử dụng cùng một lượng bộ nhớ mọi lúc.

Trong trường hợp phần tử bắt buộc chỉ phần nào ở đầu danh sách thì nó sẽ tiết kiệm được một lượng thời gian và bộ nhớ tốt.


1
xrangekhông tạo ra một cá thể lặp. Nó tạo ra một xrangeđối tượng, có thể lặp lại, nhưng không phải là một trình lặp lặp gần như (nhưng không hoàn toàn) một chuỗi, giống như một danh sách.
abarnert

1

Phạm vi trả về một danh sách trong khi xrange trả về một đối tượng xrange có cùng bộ nhớ bất kể kích thước phạm vi, như trong trường hợp này, chỉ có một phần tử được tạo và khả dụng trên mỗi lần lặp trong khi trong trường hợp sử dụng phạm vi, tất cả các phần tử được tạo cùng một lúc và có sẵn trong bộ nhớ.


1

Sự khác biệt giảm cho các đối số nhỏ hơn thành 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

Trong trường hợp xrange(100)này chỉ hiệu quả hơn khoảng 20%.


1

phạm vi: -range sẽ cư trú mọi thứ cùng một lúc. nghĩa là mọi số của phạm vi sẽ chiếm bộ nhớ.

xrange: -xrange là một cái gì đó giống như trình tạo, nó sẽ xuất hiện khi bạn muốn phạm vi số nhưng bạn không muốn chúng được lưu trữ, giống như khi bạn muốn sử dụng cho loop.so bộ nhớ hiệu quả.


1

Ngoài ra, nếu làm list(xrange(...))sẽ tương đương với range(...).

Thế listlà chậm.

Cũng xrangethực sự không hoàn thành đầy đủ trình tự

Vì vậy, đó là lý do tại sao nó không phải là một danh sách, nó là một xrangeđối tượng


1

range() trong Python 2.x

Hàm này về cơ bản là range()hàm cũ đã có sẵn trong Python 2.xvà trả về một thể hiện của một listđối tượng có chứa các phần tử trong phạm vi đã chỉ định.

Tuy nhiên, việc triển khai này quá kém hiệu quả khi bắt đầu một danh sách với một loạt các số. Ví dụ, for i in range(1000000)sẽ là một lệnh rất tốn kém để thực thi, cả về bộ nhớ và thời gian sử dụng vì nó yêu cầu lưu trữ danh sách này vào bộ nhớ.


range()trong Python 3.xxrange()trong Python2.x

Python 3.xgiới thiệu một triển khai mới hơn range()(trong khi triển khai mới hơn đã có sẵn trong Python 2.xthông quaxrange() chức năng).

Việc range()khai thác một chiến lược được gọi là đánh giá lười biếng. Thay vì tạo một danh sách lớn các phần tử trong phạm vi, triển khai mới hơn giới thiệu lớp range, một đối tượng nhẹ đại diện cho các phần tử cần thiết trong phạm vi đã cho, mà không lưu trữ chúng rõ ràng trong bộ nhớ (điều này nghe có vẻ giống như máy phát điện nhưng khái niệm đánh giá lười biếng là khác nhau).


Ví dụ, xem xét những điều sau đây:

# Python 2.x
>>> a = range(10)
>>> type(a)
<type 'list'>
>>> b = xrange(10)
>>> type(b)
<type 'xrange'>

# Python 3.x
>>> a = range(10)
>>> type(a)
<class 'range'>

-2

Xem bài này để tìm sự khác biệt giữa phạm vi và xrange:

Để trích:

rangetrả về chính xác những gì bạn nghĩ: một danh sách các số nguyên liên tiếp, có độ dài xác định bắt đầu bằng 0. xrange, tuy nhiên, trả về một "đối tượng xrange" , hoạt động rất nhiều như một trình vòng lặp


2
Tôi nhận ra đây là 5 tuổi, nhưng bài đăng đó là sai về gần như tất cả mọi thứ. xrangekhông phải là một trình vòng lặp. Danh sách được trả về bởi rangekhông hỗ trợ phép lặp (một danh sách gần như là ví dụ mẫu của một lần lặp). Lợi ích tổng thể của xrangekhông phải là "tối thiểu". Và như thế.
abarnert
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.