>>> range(1,11)
给你
[1,2,3,4,5,6,7,8,9,10]
为什么不是1-11?
他们是随机决定这样做的,还是有一些我没有看到的价值?
>>> range(1,11)
给你
[1,2,3,4,5,6,7,8,9,10]
为什么不是1-11?
他们是随机决定这样做的,还是有一些我没有看到的价值?
当前回答
它对于分割范围也很有用;Range (a,b)可以分为Range (a, x)和Range (x, b),而包含Range则可以写成x-1或x+1。虽然您很少需要分割范围,但您确实倾向于经常分割列表,这是切片列表l[a:b]包括第a个元素而不包括第b个元素的原因之一。那么range具有相同的属性会使它很好地一致。
其他回答
考虑代码
for i in range(10):
print "You'll see this 10 times", i
这个想法是,你得到一个长度为y-x的列表,你可以(如上所述)迭代。
仔细阅读python文档的范围——他们认为for-loop迭代是主要的用例。
只是在很多情况下更方便推理。
基本上,我们可以把范围看作起点和终点之间的间隔。如果start <= end,则它们之间的间隔长度为end - start。如果len实际上被定义为长度,你会得到:
len(range(start, end)) == start - end
但是,我们计算范围中包含的整数,而不是测量间隔的长度。为了保持上述性质为真,我们应该包括其中一个端点并排除另一个端点。
添加step参数就像引入一个长度单位。在这种情况下,你会期望
len(range(start, end, step)) == (start - end) / step
的长度。要得到计数,只需使用整数除法。
虽然这里有一些有用的算法解释,但我认为它可能有助于添加一些简单的“现实生活”推理,以解释为什么它是这样工作的,在向年轻的新人介绍这个主题时,我发现这很有用:
对于像“range(1,10)”这样的东西,可能会因为认为参数对代表“开始和结束”而产生混淆。
它实际上是开始和“停止”。
现在,如果它是“end”值,那么是的,您可能会期望该数字将作为序列中的最后一项包含在内。但这并不是“结束”。
其他人错误地称该参数为“count”,因为如果你只使用“range(n)”,那么它当然会迭代“n”次。当添加start参数时,这种逻辑就失效了。
所以关键是要记住它的名字:“stop”。 这意味着当到达这个点时,迭代将立即停止。在那之后就没有了。
因此,虽然“start”确实表示要包含的第一个值,但在达到“stop”值时,它会“中断”,而不是在停止之前继续处理“那个值”。
我在向孩子们解释这一点时用的一个比喻是,具有讽刺意味的是,他们比孩子们表现得更好!它不会在它应该停止的时候停止——它会在没有完成它正在做的事情之前立即停止。(他们得到了这个;))
再打个比方——当你开车时,你没有经过停车/让行/让行的标志,结果它就坐在你车旁边或后面了。从技术上讲,当你停下来时,你还没有到达它。它不包括在“你旅途中经过的东西”中。
我希望其中一些有助于向Pythonitos/Pythonitas解释!
因为调用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
你能看出如果range()恰好上升到len(li),这将是有问题的吗?程序员需要显式地减去1。这也符合程序员喜欢for(int i = 0;I < 10;i++) over for(int I = 0;I <= 9;我+ +)。
如果你频繁调用起始值为1的range,你可能需要定义自己的函数:
>>> def range1(start, end):
... return range(start, end+1)
...
>>> range1(1, 10)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
它对于分割范围也很有用;Range (a,b)可以分为Range (a, x)和Range (x, b),而包含Range则可以写成x-1或x+1。虽然您很少需要分割范围,但您确实倾向于经常分割列表,这是切片列表l[a:b]包括第a个元素而不包括第b个元素的原因之一。那么range具有相同的属性会使它很好地一致。