我试图理解Python 3在完成for循环时如何处理索引变量值。我是一名蟒蛇新手,拥有C语言的先前编程经验,所以在这一点上,我认为"在C中,尝试用Python构造等效代码。
这是一个玩具示例。 。
def tst(n): return n==6
for i in range(8,0,-1):
if tst(i): break
print(i)
for i in range(4,0,-1):
if tst(i): break
print(i)
第一个循环完成后,变量i
的值为6
,如预期的那样。
但是在第二个循环完成之后,我预计(根据我的C经验)i
的值将是0
(即i
的最终值将落在过去范围的结束,除非有中断),但实际值为1
。
我希望它是0
。
作为替代方案,我可以用这种方式编写第二个循环:
i=4
while i>0:
if tst(i): break
i-=1
print(i)
以我想要的方式工作。
是这样做的吗?
更新
感谢所有人解释Python如何解释范围表达式。
使用juanpa.arrivillaga的建议,我已经解决了以下问题。 。
for i in range(4,0,-1):
if tst(i): break
else:
i=0
print(i)
答案 0 :(得分:6)
你误解了range()
是如何运作的; stop
值不包含在内:
>>> list(range(4, 0, -1))
[4, 3, 2, 1]
如果您希望范围降至0,请使用-1
作为结束值:
>>> list(range(4, -1, -1))
[4, 3, 2, 1, 0]
来自range()
object documentation:
对于肯定的步骤,范围
r
的内容由公式r[i] = start + step*i
确定,其中i >= 0
和r[i] < stop
。对于否定步骤,范围的内容仍由公式
r[i] = start + step*i
确定,但约束为i >= 0
和r[i] > stop
。
r[i] > stop
表示它永远不会等于stop
。
您的while
循环在经过测试后递减i
,因此i > 0
仍适用于i = 1
,但您减去了1
i = 0
1}},使其成为while
,此时for
测试为假,循环结束。
请注意,您无法将Python的for
构造与C C
进行比较。 Python概念是For each loop,而while
构造实际上是 setup,test,alter 构造,它执行 setup 一次,然后重复直到测试失败,每次重复后运行 alter 指令。这就是你的i = 4
循环所做的事情; 设置为i > 0
,测试为i -= 1
,更改指令为for
at最后,在循环体的末尾。
如果你想用C语言考虑Python for
循环,我能想到的最接近的是指针上的int range[] = { 4, 3, 2, 1 }
for (int* p1=range; p1 < (range + (sizeof(range)/sizeof(range[0]))); p1++)
{
// ...
}
循环:
, 0
如果您希望继续range[]
,则必须在0
定义中添加for
。 Python public class SolrData{
private int sex;
@JsonSerialize(using = CustomSexSerializer.class)
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
循环处理任何迭代,但包括无限生成器;请参阅iterator protocol。
答案 1 :(得分:4)
那是因为停止值不包括在内。这是范围的sintax:
range([start], stop[, step])
start: Starting number of the sequence.
stop: Generate numbers up to, but not including this number.
step: Difference between each number in the sequence.
答案 2 :(得分:1)
以下是思考它的方法。在Python中,for
循环总是迭代一组对象。循环结束时,索引变量将始终保存集合中的最后一个对象。绊倒你的是Python range()
函数最后是非包容性的。请参阅https://docs.python.org/3/library/stdtypes.html#typesseq-range上的文档。
因此,在您的情况下,第二个循环正在range(4,0,-1)
上正确迭代,相当于[4, 3, 2, 1]
,而不是[4, 3, 2, 1, 0]
。因此i
以该集合中的最后一个值结束,即1.如果要在范围中包含0,则必须使用range(4, -1, -1)
。
我发现range()
的这种行为令人困惑,但它是一个非常标准的Python元素。如果你想循环重复n
次,它就可以正常工作 - 只需使用range(n)
来获得[0,1,...,n-1]。字符串和集合索引的工作方式类似:mystring[:4]
为mystring
的元素4之前的提供了所有内容。如果要分割字符串,那么这种行为可能会很好:mystring[:4]
为您提供前4个字符,然后mystring[4:]
为您提供所有内容。这样您就不必在各个地方为索引添加1,或者记得像在C中一样使用i<3
(不是i<=3
)。
另一方面,如果你想要一个从1到5(含)的数字列表,你必须记住使用像range(1, 5+1)
这样的东西。 (我有时会使用+1作为提醒,这会使范围进一步变大,以便range
调用显示某处的实际停止点。)
答案 3 :(得分:0)
问题在于range(4,0,-1)
,这会返回[4, 3, 2, 1]
将其更改为range(4,-1,-1)