【Python那些事兒】range()和xrange()
無論是range()還是xrange()都是Python裡的內建函式。這個兩個內建函式最常用在for迴圈中。range()和xrange() 在Python 2裡是兩種不同的實現。
但是在Python 3裡,range()這種實現被移除了;保留了xrange()的實現,且將xrange()重新命名成range()。
首先,我們來看Python 2裡range()。它是一個內建函式,這個函式用於建立整數等差數列,因此它常被用於for迴圈。
從官方幫助文件,我們可以看出下面的特性:
- 內建函式(built-in);
- 接受3個引數分別是start, stop和step(其中start和step是可選的,stop是必需的);
- 如果沒有指定start,預設從0開始(Python都是從0開始的);
- 如果沒有指定step,預設step是1。(step不能是0,如果指定step為0,“ValueError: range() step argument must not be zero”將會被丟擲)。
接下來看看xrange()。 xrange()雖然也是內建函式,但是它被定義成了Python裡一種型別(type),這種型別就叫xrange。我們從Python 2的interactive shell裡很容易看到這點。
從文件裡可以看出,xrange和range的引數和用法是相同的。只是xrange()返回的不再是一個數列,而是一個xrange物件。這個物件可以按需生成引數指定範圍內的數字(即元素)。由於xrange物件是按需生成單個的元素,而不像range那樣,首先建立整個list。所以,在相同的範圍內,xrange佔用的記憶體空間將更小,xrange也會更快。實際上,xrange由於是在迴圈內被呼叫時才會生成元素,因此無論迴圈多少次,只有當前一個元素佔用了記憶體空間,且每次迴圈佔用的都是相同的單個元素空間。我們可以粗略的認為,相同n個元素的話,range佔用的空間是xrange的n倍。因此,在迴圈很大情況下,xrange的高效率和快速將表現的很明顯。
總結一下:
- range()返回整個list;
- xrange()返回的是一個xrange object,且這個物件是個iterable;
- 兩者都用與for迴圈;
- xrange()佔用更少的記憶體空間,因為迴圈時xrange()只生成當前的元素,不像range()一開始就成生成完整的list。
這就是在Python 2裡range和xrange的相同點和區別。
請理解下面這句話:
“The advantage of the range type over a regular list or tuple is that a range object will always take the same (small) amount of memory, no matter the size of the range it represents (as it only stores the start, stop and step values, calculating individual items and subranges as needed).”