在C中,像这样调用strlen被认为是不好的做法:
for ( i = 0; strlen ( str ) != foo; i++ )
{
// stuff
}
当然,原因在于它效率低下,因为它会多次“计算”字符串中的字符。
然而,在Python中,我经常看到这样的代码:
for i in range ( 0, len ( list ) ):
# stuff
这是不好的做法吗?我应该将len()的结果存储在变量中并使用它吗?
答案 0 :(得分:11)
在Python中,for
循环遍历类似列表的对象,它没有每次都检查的条件语句。为了说明,以下两个循环在功能上是等效的; while
循环是for (i=0; i< n; i++) { ... }
的直接翻译,而for
循环是Pythonic的做法:
i = 0
while i < n:
# do some actions using i
i += 1
for i in range(n):
# do some actions using i
在for
循环中,在循环开始之前评估range(n)
,然后在循环中使用然后其返回值。换句话说,range(n)
被评估一次(并且只评估一次)以获取i
应该采用的值的列表*。
因此,在给定的具体示例中,Python看到for i in range(0, len(list))
,评估range(0, len(list))
(因此len
被调用一次)并存储输出(它不会调用range
(或len
)再次)。
(Python 3.x {* range
中的*实际上并不返回列表,但在for循环中使用它时功能没有区别)
答案 1 :(得分:4)
在Python中编写for i in range(len(whatever))
是一种糟糕的风格。正如其他人所提到的,可以通过for element in whatever
获得直接迭代。然而,人们总是这样做,原因有两个:
他们是C程序员,并没有直接围绕迭代。
他们希望在迭代时修改列表,否则需要索引。如果是这种情况,那么Pythonic的方法就是enumerate
函数:for i, element in enumerate(whatever)
。
答案 2 :(得分:3)
这在python中很好,因为range
函数创建了for循环随后使用的列表。因此len
只被调用一次。此外,你不需要额外的0,因为如果没有额外的选项,range
从0开始计数。
作为旁注,您通常希望使用xrange
,因为它会创建一个懒惰评估的生成器。