为什么 Python 的 Range 要设计成左开右闭区间?
原博客地址:https://www.jianshu.com/p/5eaa330788e8
Python的range()函数是左开右闭的。而且,除了Python,其他的语言似乎也有类似的设计。Edsger W. Dijkstra 在1982年写过一篇短文章分析了一下其中的原因——当然,那时候没有Python,不过内在的逻辑是相同的,与语言无关。
分析
为了表示 2,3,...,12 这样一个序列,有四种方法
- 2≤ i < 13 (左闭右开区间)
- 1< i ≤ 12 (左开右闭区间)
- 2≤ i ≤ 12 (闭区间)
- 1< i < 13 (开区间)
其中哪一种方法时最好的表示方法呢?前两种的两端表示的序列差刚好是序列长度,而且两个相邻子序列的其中一个子序列的上界就是另一个子序列的下界。所以,我们可以排除3、4的方法。那么,1和2哪种方法更好呢?
最小的自然数是0。
注意到自然数是有最小值的——最小的自然数是0。当我们的下界取 < (像第二或第四种方法那样),那么我们无法用非自然数表示。例如,表示自然数0~5,用第二种方法表示为:-1 < i ≤ 5 。这种表示方法相对于第一种,真的反常规思维。因此,我们更倾向于表示0 < i < 6 。这样,才能真正的一切从0 开始。
对于取上界,如何表示空集?第一个是符合我们直觉的。
0≤i< 0 和 0<i≤0
第三是反直觉的——上界小于下界。
0≤i≤-1
所以,综合起来,第一个式子最直观。
让我们来思考另一个问题,默认的下界是0还是1 ?
- 当从 1 开始时,下标范围是 1 ≤ i < N+1;
- 而如果从零开始,下标范围是 0 ≤ i < N;
让我们的下标从零开始吧,这样,一个元素的下标就等于当前元素之前的元素的数量了。
总结
抛去分析过程,选择第一种方法(左开右闭的原因如下):
- 上下界之差等于元素的数量。
- 易于表示两个相邻子序列,一个子序列的上界就是另一个子序列的下界。
- 序列从零(最小自然数)开始计数时,下界的下标不是 -1(非自然数)。
- 表达空集时,不会使得上界小于下界。
有志者,事竟成,破釜沉舟,百二秦关终属楚; 苦心人,天不负,卧薪尝胆,三千越甲可吞吴。