python中的左闭右开
原文链接:http://www.juzicode.com/archives/3225
先抛一个数学概念,在直线上介于固定的两点A和B之间的所有点的集合有下列4种情况:
1、开区间:不包含A,B,用(A,B)来表示
2、闭区间:包含A,B,用[A,B]来表示
3、左闭右开:包含A,不包含B,用[A,B)来表示
4、左开右闭:不包含A,包含B,用(A,B]来表示
整理成表格是这样的:
区间名称 | A,B是否包含 | 表示方法 | |
开区间 | 不包含A,B | (A,B) | |
闭区间 | 包含A,B | [A,B] | |
左闭右开 | 包含A,不包含B | [A,B) | |
左开右闭 | 不包含A,包含B | (A,B] |
在Python中很多函数、切片操作等都呈现出左闭右开现象。
1、range()函数
range()函数生成的实例,迭代时并包含左边界、不包含右边界:
#vx:桔子code / juzicode.com
rng = range(10)
print(rng)
for r in rng:
print(r, end=' ')
运行结果:
range(0, 10)
0 1 2 3 4 5 6 7 8 9
从运行结果看,10是rng的右边界,但是在迭代的时候,只是迭代到9就停止了,作为右边界的10并不在区间内。
2、切片
在字符串的切片中也有类似的用法,冒号分隔2个左、右下标,生成的新字符串左下标索引的元素包含在内但是右下标不包含。下面的例子左边从1开始右边到6,但是只取了1,2,3,4,5的5个下标所在的元素:
#vx:桔子code / juzicode.com
st = '0123456789'
stnew = st[1:6]
print(stnew)
运行结果:
12345
3、numpy数组
在numpy中很多数组生成方法也有类似的现象。
np.arange(x)会生成一个数组,步长为1,取值依次在[0,x)区间内,包含左边界0,不包含右边界x。下面这个例子中np.arange(6)生成一个包含0~5的6个数值的数组。
#vx:桔子code / juzicode.com
import numpy as np
a=np.arange(6) #arange方法创建一维数组
print(type(a))
print('a=',a)
运行结果:
<class 'numpy.ndarray'>
a= [0 1 2 3 4 5]
np.random.randint()第一个位置参数low是必须的,如果没有传入high,返回的数据范围是[0,low)的左闭右开区间内的随机整数。如果传入high,返回的数据范围是[low,high)的左闭右开区间内的随机整数。下面这个例子中a的元素取值只有0~5不包含右边界6,b的元素取值只有6~9不包含右边界10:
#juzicode.com,#VX:桔子code
import numpy as np
a = np.random.randint(6,size=(3,7))
print(type(a))
print('a=',a)
b = np.random.randint(6,10,size=(3,7))
print(type(b))
print('b=',b)
运行结果:
<class 'numpy.ndarray'>
a= [[5 0 2 2 2 5 4]
[0 3 1 2 1 1 5]
[5 1 3 2 4 3 0]]
<class 'numpy.ndarray'>
b= [[9 9 9 7 7 9 8]
[9 8 6 9 7 7 8]
[9 8 6 9 8 7 7]]
4、伪随机数
random.random()产生一个[0.0,1.0)之间的伪随机数,取值大小在可以包含0,但是小于1.0的左闭右开区间内。
#juzicode.com / VX公众号: 桔子code
import random
for i in range(5):
num = random.random()
print(num)
运行结果:
0.9759375788175713
0.623926154386807
0.5665190757083962
0.5264106376758246
0.5817898105732811
另外像random.randrange()如果使用一个参数random.randrange(stop),表示生成[0,stop)左闭右开范围内的伪随机数,如果是2个参数random.randrange(start,stop)表示生成[start,stop))左闭右开范围内的伪随机数,如果是3个参数random.randrange(start,stop,step)表示生成步长为step的[start,stop))左闭右开范围内的伪随机数。
import random
print('\nrandrange 1个参数:')
for i in range(5):
num = random.randrange(100)
print(num,end=' ')
print('\nrandrange 2个参数:')
for i in range(5):
num = random.randrange(90,100)
print(num,end=' ')
print('\nrandrange 3个参数:')
for i in range(5):
num = random.randrange(0,100,10)
print(num,end=' ')
运行结果:
randrange 1个参数:
25 53 72 70 13
randrange 2个参数:
97 97 95 91 98
randrange 3个参数:
40 20 60 10 30
例外
虽然在Python中左闭右开现象比较常见,但是并不是所有的函数或方法都满足该现象,比如numpy的linspace()却可能是在一个闭区间里取值。比如numpy.linspace(1,10,20)创建一个一维数组,数值范围包含了左边界1和右边界10。另外像random.randint(start,stop)方法,也是一个生成伪随机数的方法,但是取值范围是可能包含start和stop取值的闭区间。不过从random的源码可以看出来randint(start,stop)是对randrange()的封装,实际调用的仍然是取值左闭右开的randrange(start,stop+1)。