【发布时间】:2013-11-19 00:03:14
【问题描述】:
在 Java 中,我们可以有这样的 FOR 循环
for (i = 0; i < 10; i += 1) {
}
然而这在 Python 中是不可能的; FOR 只能在“foreach”的意义上使用,循环遍历一个可迭代对象中的每个元素。
为什么在 Python 中遗漏了 FOR 循环的控制结构?
【问题讨论】:
-
你可以用类似
xrange的东西来完成同样的事情
在 Java 中,我们可以有这样的 FOR 循环
for (i = 0; i < 10; i += 1) {
}
然而这在 Python 中是不可能的; FOR 只能在“foreach”的意义上使用,循环遍历一个可迭代对象中的每个元素。
为什么在 Python 中遗漏了 FOR 循环的控制结构?
【问题讨论】:
xrange的东西来完成同样的事情
The Zen of Python 说“应该有一种——最好只有一种——明显的方法。” Python 已经有这种方法了:
for i in xrange(10):
pass
如果您想明确所有部分,您也可以这样做:
for i in xrange(0, 10, 1):
pass
由于它已经有一个“明显”的方式来做,添加另一种方式将是 un-zen。 (那会是“nez”吗?)
(注意:在 Python 3 中,使用 range 而不是 xrange。)
C 风格的 for 循环具有更大的灵活性,但最终您可以使用 Python 的 while(或 C 的 while)编写等效循环,这不仅涉及“一种明显的方式”原则,还有“简单胜于复杂”等。当然,这完全是品味问题——在这种情况下,是 Guido van Rossum 的品味。
【讨论】:
cython 足够聪明,可以将这些循环特殊化为 c 风格的 for 循环,而无需 xrange 的开销。如果pypy 也能认出它,我不会感到惊讶。
由于这是可以追溯到 Python 0.x 的迷雾中的问题之一(事实上,很可能是它的前身 ABC),唯一能真正回答的人是 Guido,而且只有在他记得的情况下。您可以尝试让他在他的 History of Python 博客上写一篇文章。
但是,这有一些很好的理由。
首先,只有for 的一种形式而不是两种不同的形式使语言更小——更易于人类学习和阅读,更易于计算机解析。
没有“foreach”风格的for 循环会导致很多错误,并使很多简单的代码更加冗长。
没有 C 风格的 for 循环会使一些已经非常复杂的 for 循环变得稍微复杂一些,因为它们强制它们成为 while 循环。它不会影响像你这样的简单循环,可以写成“foreach”循环,比如for i in range(10):——更简洁,更易读,更难出错。*
这样看,选择是显而易见的。
* 事实上,即使是复杂 循环也可以通过迭代器转换为foreach 循环。有时这是个好主意。例如,for (int i=2; i=next_prime(i); i<1000000) 真的比for i in takewhile(lambda i: i<1000000, generate_primes()): 好吗?有一个原因,C++ 逐渐添加了使后者成为可能的功能,以避免您在使用前者时容易犯的错误……
【讨论】:
一般来说,迭代元素的性能更好。你可以得到相同的结果:
for i in xrange(0, 20):
pass
你应该明确地阅读 python 的 zed: http://www.python.org/dev/peps/pep-0020/
【讨论】:
因为它只是一个while循环的语法糖
i = 0
while i < 10:
# stuff
i += 1
如果您从未在 C 风格的 for 循环中遇到过一个错误,请举手。是这样想的。
【讨论】:
while 循环来说是 not 语法糖,因为如果你在 C 风格的 for 循环中 continue,那么继续代码i += 1 被执行。在while 循环中并非如此。在这种情况下,“明显”的解决方法是将i += 1 放在循环的开头,将i = 0 更改为i = -1 并将i < 10 更改为i < 9,但可能会出现一些混乱尝试为 :-) 编写完全等效的 C 风格
for、while 或while True: … break …,我将花哨的位放入genexpr(或itertools 调用或... ) 然后它就变成了一个明显的for 循环,其中break 和continue 的意思正是你想要的......