python中xrange和range
阿新 • • 發佈:2019-01-29
說到序列,我們第一想到的是一組有序元素組成的集合。同時,每個元素都有唯一的下標作為索引。
在Python中,有許多內界的序列。包括元組tuple,列表list,字串str等。上面提到的序列型別(list,tuple,str)有一個共同的特點,就是當序列物件建立時,需要開闢專門的記憶體空間,儲存序列中的所有元素。換句話說,這些序列物件本質上,是一個集合。
例如,下面程式碼建立了一個序列物件s。在該物件序列建立時,需要開闢記憶體空間將序列中的3個元素(整數1,2,3)儲存下來。
s=[1,2,3]
然而,根據python官方文件的定義,一個序列物件不必要儲存所有的元素。一般來說,一個序列物件至少需要實現如下兩個方法。
- _len_ 方法。該方法返回序列長度,也即序列中元素個數。
- _getitem_方法。該方法有一個整型引數(不妨記為index)。它需要返回序列中下標為index的元素的值。
例如,下面的程式碼定義了一個序列型別。
class MyRange:
def __init__(self, start, end):
self.start = start
self.end = end
def __len__(self):
return self.end - self.start
def __getitem__ (self, index):
if index < 0 or index >= len(self):
raise IndexError
return index + self.start
它定義的是從start到end-1之間所有整陣列成的序列。
- 程式碼中的len方法返回序列的長度。
- 程式碼中的_getitem_方法返回序列中第index個元素。其中第10-11行判斷index的是否越界。值得一提的是,第10行呼叫的len方法是Python的內建方法,它會呼叫序列物件的_len_方法。可以想見,_getitem_
下面的測試程式碼
myrange = MyRange(0, 10)
print myrange[9]
print myrange[10]
輸出如下
Traceback (most recent call last):
File "test.py", line 25, in <module>
print myrange[10]
File "test.py", line 19, in __getitem__
raise IndexError
IndexError
當然,在Python中,序列的下標是可以為負的。因此,我們對getitem方法做如下修改。
class MyRange:
def __getitem__(self, index):
index = index if index >= 0 else index + self.end
if index < 0 or index >= len(self):
raise IndexError
return index + self.start
測試程式碼
myrange = MyRange(0, 10)
print myrange[-1]
print myrange[-2]
輸出結果
9
8
有了上面的介紹以後,我們可以很容易理解python中range方法與xrange方法區別了。
range方法返回的是一個list物件,它需要開闢專門的空間儲存序列中所有的元素。
xrange方法返回的是xrange物件,它是一個序列物件,但並不儲存序列中的元素。其實現方法與本文介紹的MyRange型別類似。
因此,如果只對序列進行讀操作,xrange方法效率較高;但是如果需要改變序列的元素,或者需要往序列增刪元素,那隻能通過range方法生成一個list物件。