为什么范围(开始,结束)不包括结束?

Met*_*uru 280 python range

>>> range(1,11)
Run Code Online (Sandbox Code Playgroud)

给你

[1,2,3,4,5,6,7,8,9,10]
Run Code Online (Sandbox Code Playgroud)

为什么不1-11?

他们是否只是随意决定这样做,或者它是否具有一些我没有看到的价值?

mar*_*cog 225

因为调用range(0, 10)哪个返回[0,1,2,3,4,5,6,7,8,9]包含10个等于的元素更常见len(range(0, 10)).请记住,程序员更喜欢基于0的索引.

另外,请考虑以下常见代码段:

for i in range(len(li)):
    pass
Run Code Online (Sandbox Code Playgroud)

你能不能看到如果range()真的len(li)那么这会有问题吗?程序员需要显式减1.这也遵循程序员喜欢的共同趋势for(int i = 0; i < 10; i++)for(int i = 0; i <= 9; i++).

如果您经常以1开头调用范围,则可能需要定义自己的函数:

>>> def range1(start, end):
...     return range(start, end+1)
...
>>> range1(1, 10)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Run Code Online (Sandbox Code Playgroud)

  • 如果那是推理,参数不是"范围(开始,计数)"? (45认同)
  • `for in in range(len(li)):`是反模式.一个人应该使用`enumerate`. (7认同)
  • 你解释范围(x)应该从0开始,x将是"范围的长度".好.但是你没有解释为什么range(x,y)应该从x开始并以y-1结束.如果程序员想要i的范围从1到3的for循环,他必须明确地添加1.这真的是为了方便吗? (6认同)
  • 你的`range1`不适用于步长大于1的范围. (4认同)
  • @shogun起始值默认为0,即`range(10)`相当于`range(0,10)`. (3认同)

sep*_*p2k 23

独家系列确实有一些好处:

一方面,每个项目range(0,n)都是长度列表的有效索引n.

range(0,n)有一个长度n,而不是n+1包容范围.


din*_*les 23

虽然这里有一些有用的算法解释,但我认为这可能有助于添加一些简单的"现实生活"推理,说明为什么它以这种方式工作,我在将这个主题介绍给年轻的新人时发现了这些推理:

对于像"范围(1,10)"这样的东西,可以通过认为一对参数代表"开始和结束"来产生混淆.

它实际上是开始和"停止".

现在,如果它 "结束"值,那么,是的,您可能希望该数字将作为序列中的最终条目包含在内.但这不是"结束".

其他人错误地称该参数为"count",因为如果你只使用'range(n)'那么它当然会迭代'n'次.添加start参数时,此逻辑会中断.

所以关键是要记住它的名字:" 停止 ".这意味着,当达到时,迭代将立即停止.不是之后.

因此,虽然"开始"确实代表了要包含的第一个值,但在达到"停止"值时,它"打破"而不是在停止之前继续处理"那个".

我用来向孩子们解释这个问题的一个类比是,具有讽刺意味的是,它比孩子更好!它应该它应该没有停止- 它立即停止而不完成它正在做的事情.(他们得到了这个;))

另一个类比 - 当你驾驶汽车时,你没有通过停止/收益/'让路'的标志,并最终坐在汽车旁边或后面的某个地方.从技术上讲,当你停下来时,你仍然没有达到它.它不包括在"你旅途中传递的东西"中.

我希望其中一些有助于向Pythonitos/Pythonitas解释!

  • 你正试图给猪涂口红。“停止”和“结束”之间的区别是荒谬的。如果我从 1 到 7,我还没有通过 7。对于开始和停止位置有不同的约定,这只是 Python 的一个缺陷。在其他语言(包括人类语言)中,“从 X 到 Y”的意思是“从 X 到 Y”。在 Python 中,“X:Y”表示“X:Y-1”。如果您在 9 点到 11 点开会,您会告诉人们是从 9 点到 12 点,还是 8 点到 11 点? (6认同)
  • 这个解释比较直观。谢谢 (3认同)
  • @bzip2,Python 不是猪,而是蛇。您所说的“不一致”和“缺陷”并不是:它们是开发人员做出的设计选择,在整个语言中保持一致,并允许数百万程序员解决他们的任务。如果您不喜欢它,请使用提供包含范围的扩展或切换到其他语言。您的评论无助于理解 Python,反而冒犯了社区。它们还表明您未能理解独占时间间隔的本质,因为如果您在 9 点到 11 点之间开会,那么 11 点您就有空。 (2认同)
  • 喜欢停车标志的比喻,抱歉盗用了:) (2认同)

kin*_*all 18

它与零基索引和len().例如,如果列表中有10个项目x,则编号为0-9.range(len(x))给你0-9.

当然,人们会告诉你这是更Python做for item in xfor index, item in enumerate(x)不是for i in range(len(x)).

切片也是这样的:foo[1:4]是项目1-3 foo(记住,由于从零开始的索引,项目1实际上是第二项).为了保持一致性,它们应该以相同的方式工作.

我认为它是:"你想要的第一个号码,然后是你想要的第一个号码." 如果你想要1-10,你不想要的第一个数字是11,所以就是这样range(1, 11).

如果它在特定的应用程序中变得很麻烦,那么编写一个小的辅助函数就足够了,它可以在结束索引和调用中加1 range().


xua*_*nji 12

它对于分割范围也很有用; range(a,b)可以分为range(a, x)range(x, b),而在包含范围,你会写x-1x+1.虽然您很少需要分割范围,但您确实倾向于经常拆分列表,这是切片列表l[a:b]包括第a个元素但不包括第b个元素的原因之一.然后range具有相同的属性使其非常一致.


Ski*_*ick 11

范围的长度是最高值减去最低值.

它非常类似于:

for (var i = 1; i < 11; i++) {
    //i goes from 1 to 10 in here
}
Run Code Online (Sandbox Code Playgroud)

用C风格的语言.

也像Ruby的范围:

1...11 #this is a range from 1 to 10
Run Code Online (Sandbox Code Playgroud)

但是,Ruby认识到很多时候你想要包含终端值并提供替代语法:

1..10 #this is also a range from 1 to 10
Run Code Online (Sandbox Code Playgroud)

  • 尔加!我不使用Ruby,但我可以想象`1..10` vs`1 ... 10`在阅读代码时很难区分! (16认同)
  • Ruby的范围运算符非常直观.较长的形式可以让您获得更短的序列.*咳嗽* (11认同)
  • @marcog - 当你知道这两种形式存在时,你的眼睛会调整差异:) (5认同)
  • @Russell,也许1 ............ 20应该给出与1..10相同的范围.现在这将是一些值得转换的语法糖.;) (4认同)
  • @Russell额外的点挤出范围外的最后一项:) (4认同)

Rob*_*ert 5

考虑代码

for i in range(10):
    print "You'll see this 10 times", i
Run Code Online (Sandbox Code Playgroud)

这个想法是你得到一个 length 列表y-x,你可以(如上所见)迭代它。

阅读Python 文档的范围 - 他们认为 for-loop 迭代是主要用例。


小智 5

基本上在python中range(n)迭代n时间,这是排他性,这就是为什么它在打印时不给出最后一个值的原因,我们可以创建一个给出包容性值的函数,这意味着它也将打印范围中提到的最后一个值。

def main():
    for i in inclusive_range(25):
        print(i, sep=" ")


def inclusive_range(*args):
    numargs = len(args)
    if numargs == 0:
        raise TypeError("you need to write at least a value")
    elif numargs == 1:
        stop = args[0]
        start = 0
        step = 1
    elif numargs == 2:
        (start, stop) = args
        step = 1
    elif numargs == 3:
        (start, stop, step) = args
    else:
        raise TypeError("Inclusive range was expected at most 3 arguments,got {}".format(numargs))
    i = start
    while i <= stop:
        yield i
        i += step


if __name__ == "__main__":
    main()
Run Code Online (Sandbox Code Playgroud)


Thu*_*rea 5

pythonrange(n)中的返回从0到n-1。分别是range(1,n)从1到n-1。因此,如果您想省略第一个值并获取最后一个值 (n),您可以使用以下代码非常简单地完成。

for i in range(1, n + 1):
        print(i) #prints from 1 to n
Run Code Online (Sandbox Code Playgroud)