master
/ 3.3.3 rang.ipynb

3.3.3 rang.ipynb @masterview markup · raw · history · blame

Notebook

3.5 Range

range 类型表示不可变的数字序列,通常用于在 for 循环中指定循环次数,是for循环中应用最广泛的可迭代对象之一。
range()是python中的一个内置函数,用于生成一系列连续的整数,创建一个整数列表,一般用在 for 循环中。
range()函数既可用于控制循环,又可以用等差数列中的数求解很多数学问题。
range()函数语法:

In [2]:
# range(stop)                # 0, 1, 2, 3, 4, …stop-1,初值为0,步长为1的等差数列
# range(start, stop[, step]) # start, start+step, start+2*step…,步长为step的等差数列

for i in range(10):
    print(i)
0
1
2
3
4
5
6
7
8
9
start 和 step 是可选参数,缺省时,start=0, step=1。 range 生成的内容: r[i] = start + step * i 当 step 为正数,要求 i >= 0 且r[i] < stop; 当 step 为负数,要求 i >= 0 且 r[i] > stop。 range()具有一些特性:

1.要全部输出range()生成的序列,不能直接输出range(n)

可以用print(__list__(range(n))) 的方法,将生成的序列转成列表形式输出。
可以用print(__tuple__(range(n)))的方法,将生成的序列转成元组的形式输出。
可以用print(__*__(range(n)))将其内容解包输出。

In [3]:
print(range(5))         # 输出range(0, 5),此语句不能输出整数序列
print(list(range(5)))   # 输出[0, 1, 2, 3, 4]
print(tuple(range(5)))  # (0, 1, 2, 3, 4)
print(*range(5))        # 解包输出:0 1 2 3 4
range(0, 5)
[0, 1, 2, 3, 4]
(0, 1, 2, 3, 4)
0 1 2 3 4

练一练1

编程第一行输出从0到10的整数列表、第二行输出从0到10的整数列表元组,第三行输出从0到10的整数,各数字间用空格分隔。

In [8]:
# 补充你的代码
23
21
19
17
15
13
11
9
In [ ]:
测试用例
输出
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
0 1 2 3 4 5 6 7 8 9

2. start、stop、step都必须是__整数__,否则抛出TypeError异常。

当 stop 值小于start 值且步长为正数时,返回的序列为空。

In [ ]:
print(range(3.5))
In [ ]:
print(range(1, 8))   # 8.0是值等于整数8的浮点数,不是整数
In [ ]:
print(list(range(8, 1)))  # range(8, 1)返回空序列,转列表结果为空列表

3. 如果__start__参数缺省,默认值为__0__

如果__step__参数缺省,默认值为__1__
当试图设置__step__为0时,会抛出ValueError异常。

In [ ]:
# start参数缺省,默认值为0
print(*(range(8)))     # *将range对象解包,取出里面对象输出0 1 2 3 4 5 6 7
print(list(range(8)))  # range(8)返回空序列,转列表结果为空列表[0, 1, 2, 3, 4, 5, 6, 7]
In [ ]:
# step参数缺省,默认值为1
print(*(range(1, 8)))     # 输出1 2 3 4 5 6 7
print(list(range(1, 8)))  # 输出[1, 2, 3, 4, 5, 6, 7]

# step值为2
print(*(range(1, 8, 2)))  # 输出1 3 5 7
In [ ]:
print(*(range(1, 8, 0)))  # step为0时,会抛出ValueError异常

4. 当step是正整数时,产生的序列__递增__; 当step为负整数时,生成的序列__递减__

In [6]:
print(*(range(1, 8, 2)))   # step是正整数时,产生的序列递增
print(*(range(8, 1, -2)))  # step为负整数时,生成的序列递减
1 3 5 7
8 6 4 2

练一练2

编程在一行中输出从1到50的奇数,各数字间用空格分隔

In [ ]:
# 补充你的代码
测试用例: 输出 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49

5. range()函数产生一个__左闭右开__的序列

In [ ]:
print(*(range(5)))       # 输出0 1 2 3 4,包含左边界0,不包括右边界5
print(*(range(1, 5)))
print(*(range(1, 5, 2)))

练一练3

编程在一行中输出从1到10的整数,各数字间用空格分隔

In [ ]:
# 补充你的代码
测试用例: 输出 1 2 3 4 5 6 7 8 9 10

6. range()函数产生的是__可迭代对象__,不是迭代器,也不是列表类型。

可迭代对象(Iterable):

凡是可以作用于for循环的对象都是可迭代对象,可用collections模块的Iterable来判断。

迭代器(Iterator):

不仅可以作用于for循环,还能作用于next()函数的对象是迭代器,表示一个惰性计算的序列,可用collections模块的Iterator来判断。

In [ ]:
from collections import Iterable, Iterator

print(isinstance(range(8), Iterable))  # 查看是否为可迭代对象,结果 True
print(isinstance(range(8), Iterator))  # 查看是否为迭代器,结果 False
In [ ]:
for i in range(1, 10):
    print(i)  # 分行输出1到9的数字
In [ ]:
for i in range(1, 10):
    print(f'{i} x 1 = {1*i}', end=' ')  # 输出乘法表的一行
# 1 x 1 = 1 2 x 1 = 2 3 x 1 = 3 4 x 1 = 4 5 x 1 = 5 6 x 1 = 6 7 x 1 = 7 8 x 1 = 8 9 x 1 = 9  

7. range对象是__不可变数据类型__,可用__索引、切片__等操作__获取__其中部分数据,但不可修改其中的数据。

In [ ]:
print(range(10)[2])    # 索引,根据序列返回一个元素,2
print(range(10)[2:5])  # 切片,返回序列的一部分,range(2, 5)
range(10)[2] = 5       # 修改range中序号为2的元素的值,触发异常

惰性求值

range()函数相对于列表和元组的优点在于占用内存固定,占用内存较小,他仅存储start、stop和step值,在需要时通过计算生成序列中的每个值。

print(range(10))会输出对象range(0, 10),说明range采用了惰性求值的方式产生数据,使用print()函数打印range数据并不能直接看到range数据的具体元素。但可以通过将其转换为列表或元组的方式,查看其生成的具体数据。

range(10000)可以按顺序产生一组数字0 , 1, 2, 3, 4,… 9998, 9999,但并不会一次将这些数据生成放在内存中,只有使用到其中的某个值时,range才会产生该值,可以减少生成数据和将数据写入内存的时间开销,对于某些应用来讲效率会非常高。如下例所示:

In [ ]:
for i in range(1000000000):  # 存储的是range(1,1000000000)对象
    if i < 5:
        print(i, end=' ')    # 输出0 1 2 3 4,只产生这5个数字

range()函数常与for和控制变量一起使用,遍历range()数列中的数并控制循环次数。

In [ ]:
for <variable> in range([start,]stop[,step]):
    <语句块>

variable 为循环控制变量,经常用i、j等表示,每次循环从range()产生的数列中依次取一个值。首次进入循环时,变量取最小的值,即start值,当start缺省时,取值为0,后面每次循环依次取前一个值加步长step的值,当step值缺省时,取前一个值加1。