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)。

扩展阅读:

  1.  Python进阶教程m15–random伪随机数模块
  2.  NumPy数组的属性和常用创建方法

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注