为什么范围(开始,结束)不包括结束?
>>> range(1,11)
给你
[1,2,3,4,5,6,7,8,9,10]
为什么不1-11?
他们是不是就这样随便做了呢,还是有一些我没有看到的价值呢?
因为调用返回[0,1,2,3,4,5,6,7,8,9]
其中包含10个元素等于len(range(0, 10))
[0,1,2,3,4,5,6,7,8,9]
range(0, 10)
[0,1,2,3,4,5,6,7,8,9]
range(0, 10)
更为常见。 请记住,程序员更喜欢基于0的索引。
另外,请考虑以下常见的代码片段:
for i in range(len(li)): pass
你能否看到,如果range()
上升到len(li)
,这将是有问题的? 程序员需要明确地减去1.这也符合程序员宁愿for(int i = 0; i < 10; i++)
不是for(int i = 0; i <= 9; i++)
的普遍趋势。
如果您经常以1开始调用范围,则可能需要定义自己的函数:
>>> range1 = lambda start, end: range(start, end+1) >>> range1(1, 10) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
独有的范围确实有一些好处:
一个range(0,n)
的每个项目range(0,n)
是长度为n
列表的有效索引。
同样range(0,n)
的长度为n
,而不是n+1
,这是一个包含范围。
它与零len()
引和len()
结合使用。 例如,如果列表x
有10个项目,则它们编号为0-9。 range(len(x))
给你0-9。
当然,人们会告诉你, for item in x
或for index, item in enumerate(x)
而不是for i in range(len(x))
Pythonic会更加困难。
切片也是这样工作的: foo[1:4]
是foo
1-3项(记住,由于基于零的索引,项目1实际上是第二项)。 为了一致性,他们都应该以同样的方式工作。
我把它想成:“你想要的第一个数字,然后是你不想要的第一个数字。 如果你想要1-10,你不想要的第一个数字是11,所以它的range(1, 11)
。
如果在一个特定的应用程序中变得很麻烦,写一个辅助函数就足够简单了,该函数将1加到结尾索引处并调用range()
。
虽然在这里有一些有用的algorithm解释,但我认为这样做可能有助于增加一些简单的“现实生活”推理,为什么它以这种方式工作,在向新人介绍主题时我发现它有用:
像“范围(1,10)”这样的东西,可能会由于认为参数对代表“开始和结束”而产生混淆。
这实际上是开始和“停止”。
现在,如果它是 “最终”的价值,那么,是的,你可能期望这个数字将被包含在序列中的最后一个条目中。 但这不是“终点”。
其他人错误地称这个参数为“count”,因为如果你只使用“range(n)”,那么它当然会重复“n”次。 当你添加启动参数时,这个逻辑会崩溃。
所以关键是要记住它的名字:“ 停止 ”。 这意味着当达到迭代时,它将立即停止。 不是在那之后 。
所以,“开始”确实代表了要包含的第一个价值,在达到“停止”价值时,它“打破”,而不是在停止之前继续处理“那个”。
我用这个比喻来向孩子们解释这一点,讽刺的是,这比孩子们performance得更好! 它不应该停止后 ,它会立即停止,没有完成它在做什么。 (他们得到这个;))
另一个比喻 – 当你驾驶一辆车时,你不会通过停止/屈服/“让路”标志,并最终坐在你的车旁边或后面。 从技术上讲,当你停下来的时候,你还没有达到目的。 它不包括在“你在旅途中传递的东西”中。
我希望有一些帮助解释Pythonitos / Pythonitas!
这对于分割范围也是有用的。 range(a,b)
可以分为range(a, x)
和range(x, b)
,而在包含范围内,您可以写入x-1
或x+1
。 虽然你很less需要分割范围,但你确实倾向于经常分割列表,这是切分列表的原因之一l[a:b]
包含第a个元素,而不是第b个元素。 然后具有相同属性的range
使得它很好地一致。
范围的长度是顶部值减去底部值。
这类似于类似的东西:
for (var i = 1; i < 11; i++) { //i goes from 1 to 10 in here }
以C风格的语言。
也像Ruby的范围:
1...11 #this is a range from 1 to 10
然而,Ruby认识到,很多时候你会想要包含terminal值,并提供了另一种语法:
1..10 #this is also a range from 1 to 10
考虑代码
for i in range(10): print "You'll see this 10 times", i
这个想法是,你得到一个长度为yx
的列表,你可以(如你所见)迭代。
阅读Python文档的范围 – 他们认为循环迭代是主要的用例。