1. 程式人生 > >python中xrange和range(轉)

python中xrange和range(轉)

log item .py 對象 nbsp net range all file

說到序列,我們第一想到的是一組有序元素組成的集合。同時,每個元素都有唯一的下標作為索引。

在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] 

輸出如下

9  
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對象。

轉自:http://blog.csdn.net/hedan2013/article/details/55000018

python中xrange和range(轉)