by Harrison Feng in Python

无论是range()还是xrange()都是Python里的内置函数。这个两个内置函数最常用在for循环中。例如:

  1. >>> for i in range(5):
  2. ... print i
  3. ...
  4. 0
  5. 1
  6. 2
  7. 3
  8. 4
  9. >>> for i in xrange(5):
  10. ... print i
  11. ...
  12. 0
  13. 1
  14. 2
  15. 3
  16. 4
  17. >>>

range()和xrange() 在Python 2里是两种不同的实现。但是在Python 3里,range()这种实现被移除了; 保留了xrange()的实现,且将xrange()重新命名成range()。
首先,我们来看Python 2里range()。它是一个内置函数,这个函数用于创建整数等差数列。因此它 常被用于for循环。下面是range()的官方帮助文档。

  1. Help on built-in function range in module __builtin__:
  2. range(...)
  3. range(stop) -> list of integers
  4. range(start, stop[, step]) -> list of integers
  5. Return a list containing an arithmetic progression of integers.
  6. range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
  7. When step is given, it specifies the increment (or decrement).
  8. For example, range(4) returns [0, 1, 2, 3]. The end point is omitted!
  9. These are exactly the valid indices for a list of 4 elements.
  10. (END)

从官方帮助文档,我们可以看出下面的特性: 1、内置函数(built-in) 2、接受3个参数分别是start, stop和step(其中start和step是可选的,stop是必需的) 3、如果没有指定start,默认从0开始(Python都是从0开始的) 4、如果没有指定step,默认step是1。(step不能是0,如果指定step为0,“ValueError: range() step argument must not be zero”       将会被抛出。 额外的特性: 1、当step为正数时,start应该小于stop,否则将生成[ ],即空数列。

  1. >>> range(-3)
  2. []
  3. >>> range(5, 1)
  4. []
  5. >>> range(1,1)
  6. []

2、当step为负数时,start应该大于stop,否则将生成[ ],即空数列。 这两个特性说明range()可以生成递增和递减的数列。 下面是range()生成数列的例子:

  1. >>> range(5)
  2. [0, 1, 2, 3, 4]
  3. >>> range(1,8,3)
  4. [1, 4, 7]
  5. >>> range(0, -10)
  6. []
  7. >>> range(0, -10, -2)
  8. [0, -2, -4, -6, -8]
  9. >>>

接下来看看xrange()。 xrange()虽然也是内置函数,但是它被定义成了Python里一种类型(type), 这种类型就叫xrange。我们从Python 2的interactive shell里很容易看到这点。

  1. >>> range
  2. <built-in function range>
  3. >>> xrange
  4. <type 'xrange'>
  5. >>>

我们再来看看xragne的官方帮助文档:

  1. Help on class xrange in module __builtin__:
  2. class xrange(object)
  3. |  xrange(stop) -> xrange object
  4. |  xrange(start, stop[, step]) -> xrange object
  5. |
  6. |  Like range(), but instead of returning a list, returns an object that
  7. |  generates the numbers in the range on demand.  For looping, this is
  8. |  slightly faster than range() and more memory efficient.
  9. |
  10. |  Methods defined here:
  11. |
  12. |  __getattribute__(...)
  13. |      x.__getattribute__('name') <==> x.name
  14. |
  15. |  __getitem__(...)
  16. |      x.__getitem__(y) <==> x[y]
  17. |
  18. |  __iter__(...)
  19. |      x.__iter__() <==> iter(x)
  20. |
  21. |  __len__(...)
  22. |      x.__len__() <==> len(x)
  23. |
  24. |  __reduce__(...)
  25. |
  26. |  __repr__(...)
  27. |      x.__repr__() <==> repr(x)
  28. |
  29. |  __reversed__(...)
  30. |      Returns a reverse iterator.
  31. |
  32. |  ----------------------------------------------------------------------
  33. |  Data and other attributes defined here:
  34. |
  35. |  __new__ =
  36. |      T.__new__(S, ...) -> a new object with type S, a subtype of T
  37. (END)

从文档里可以看出,xrange和range的参数和用法是相同的。只是xrange()返回的不再是一个数列,而是一个 xrange对象。这个对象可以按需生成参数指定范围内的数字(即元素)。由于xrange对象是按需生成单个的 元素,而不像range那样,首先创建整个list。所以,在相同的范围内,xrange占用的内存空间将更小,xrange 也会更快。实际上,xrange由于是在循环内被调用时才会生成元素,因此无论循环多少次,只有当前一个元素 占用了内存空间,且每次循环占用的都是相同的单个元素空间。我们可以粗略的认为,相同n个元素的话,range占 用的空间是xrange的n倍。因此,在循环很大情况下,xrange的高效率和快速将表现的很明显。我们可以用timeit 来测试一下range和xrange的执行时间。

  1. >>> timeit.timeit('for i in range(10000000): pass',number=1)
  2. >>> timeit.timeit('for i in xrange(10000000): pass',number=1)
  3. 0.2595210075378418

在大量循环的条件下,可以看到xrange的高效率是很明显的。
总结一下: 1、range()返回整个list。 2、xrange()返回的是一个xrange object,且这个对象是个iterable。 3、两者都用与for循环。 4、xrange()占用更少的内存空间,因为循环时xrange()只生成当前的元素,不像range()一开始就成生成完整的list。 这就是在Python 2里range和xrange的相同点和区别。
那么在Python 3里,我们在前面提到了range()被移除了,xrange()被重新命名成了range()。它们之间有区别吗? 请看下面的代码 Python 2的xrange()

  1. Python 2.7.6 (default, Dec  5 2013, 23:54:52)
  2. [GCC 4.6.3] on linux2
  3. Type "help", "copyright", "credits" or "license" for more information.
  4. >>> x = xrange(5)
  5. >>> x
  6. xrange(5)
  7. >>> x[:]
  8. Traceback (most recent call last):
  9. File "", line 1, in <module>
  10. TypeError: sequence index must be integer, not 'slice'
  11. >>> x[-1]
  12. 4
  13. >>> list(x)
  14. [0, 1, 2, 3, 4]
  15. >>> dir(x)
  16. ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__iter__', '__len__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
  17. >>>

Python 3的range()

  1. Python 3.3.4 (default, Feb 23 2014, 23:07:23)
  2. [GCC 4.6.3] on linux
  3. Type "help", "copyright", "credits" or "license" for more information.
  4. >>> x = range(5)
  5. >>> x
  6. range(0, 5)
  7. >>> x[:]
  8. range(0, 5)
  9. >>> x[:3]
  10. range(0, 3)
  11. >>> list(x)
  12. [0, 1, 2, 3, 4]
  13. >>> x[-1]
  14. 4
  15. >>> dir(x)
  16. ['__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index', 'start', 'step', 'stop']
  17. >>>

很明显,range object在Python里增加了新的attributes,'count', 'index', 'start', 'step', 'stop', 且能支持slicing。Python 3的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).
到这里,我们应该比较清楚range和xrange的区别了。

by Harrison Feng in Python

【Python那些事儿之十】range()和xrange()的更多相关文章

  1. python(47):range和xrange的区别和联系

    range([start,] stop[, step]),根据start与stop指定的范围以及step设定的步长,生成一个序列. 比如: >>> range(5)[0, 1, 2, ...

  2. Python从题目中学习:range()和xrange()

    近期给公司培训Python,好好啃了啃书本,查了查资料,总结一些知识点. --------------------------------------------------------------- ...

  3. [Python]range与xrange用法对比

    [整理内容]具体如下: 先来看如下示例:>>>x=xrange(0,8)>>> print xxrange(8)>>>print x[0]0> ...

  4. Python中的range和xrange区别

    range 函数说明:range([start,] stop[, step]),根据start与stop指定的范围以及step设定的步长,生成一个序列. range示例: >>> r ...

  5. python 基础 2.7 range与xrange的区别

    #/usr/bin/python #coding=utf-8 #@Time :2017/10/25 19:22 #@Auther :liuzhenchuan #@File :range与xrange的 ...

  6. python基础-2 编码转换 pycharm 配置 运算符 基本数据类型int str list tupple dict for循环 enumerate序列方法 range和xrange

    1.编码转换 unicode 可以编译成 UTF-U GBK 即 #!/usr/bin/env python # -*- coding:utf-8 -*- a = '测试字符' #默认是utf-8 a ...

  7. python 中range与xrange的区别

    先来看看range与xrange的用法介绍 help(range)Help on built-in function range in module __builtin__: range(...) r ...

  8. python中的range与xrange

    range 也是一种类型(type),它是一个数字的序列(s sequence of numbers),而且是不可变的,通常用在for循环中. class range(stop) class rang ...

  9. python中range、xrange和randrange的区别

    range 函数说明:range([start,] stop[, step]),根据start与stop指定的范围以及step设定的步长,生成一个列表. xrange 函数说明:和range 的用法完 ...

随机推荐

  1. mfc中 控件 对话框 添加颜色 背景图片

    1 设置对话框透明 在设置控件颜色中要使用 nCtlColor Contains one of the following values, specifying the type of control ...

  2. python的进程与线程

    一.进程与线程的相关概念 1.什么是进程 进程是一个程序在一个数据集上的一次动态执行过程. 进程一般由程序,数据集,进程控制块三部分组成. 2.什么是线程 线程也叫轻量级进程,它是一个基本的CPU执行 ...

  3. Hibernate 中一对多和多对多映射

    1. 一对多映射 1.1 JavaWeb 一对多建表原则 多方表的外键指向一方表的主键; 1.2 编写一对多的 JavaBean // 客户(一方)和联系人(多方) // 客户(一方) JavaBea ...

  4. Django - ModelForm组件

    一.ModelForm组件 这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,先来一个简单的例子来看一下这个东西怎么用:比如我们的数据库中有这样一张学生表, ...

  5. 利用EasySQLMAIL实现自动填写Excel表格并发送邮件(2)

    利用EasySQLMAIL实现自动填写Excel表格并发送邮件 转自:http://blog.sina.com.cn/s/blog_1549483b70102witg.html 前一篇博文中记录了“利 ...

  6. Android Studio设置行宽、格式化断行

    设置基于Android studio 1.2,其它版本可能位置不大一样,可以直接搜索 1.设置行宽 就是那条右标准线的位置:Setting-->Editor-->Code Style,右侧 ...

  7. 基于mondrain 的原理纠正特殊指标值

    原文地址:http://www.cnblogs.com/qiaoyihang/p/7348385.html 下面有两张表 数学试卷成绩 表1 学号 省份 批次 学校 试卷成绩 数学试卷小题成绩 表2 ...

  8. c++ 11nullptr

    1. 引入nullptr的原因 引入nullptr的原因,这个要从NULL说起.对于C和C++程序员来说,一定不会对NULL感到陌生.但是C和C++中的NULL却不等价.NULL表示指针不指向任何对象 ...

  9. 浅析造成 JS 内存泄露的几种原因及解决方案

    内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束.在C++中,因为是手动管理内存,内存泄露是经常出现的事情.而现在流行的C#和Java等语言采用了自动垃圾回收方法管理内存,正常使 ...

  10. Linq To Object多字段组合唯一校验

    1.第一种方式 if(partsSalesOrderTypes.GroupBy(entity => new { entity.Name, entity.Code }).Any(array =&g ...