2012-03-31 76 views
4

在C,它被认为是不好的做法,调用strlen这样的:在循环的条件语句中调用len()是否正确?

for (i = 0; strlen (str) != foo; i++) 
{ 
    // stuff 
} 

究其原因,当然是,它是低效的,因为它“罪状”,在一个字符串多次的字符。

然而,在Python,我看到这样的代码往往:

for i in range (0, len (list)): 
    # stuff 

这是不好的做法?我应该将len()的结果存储在一个变量中并使用它吗?

+5

我希望你看不到这样的代码,但是出于完全不同的原因:Python提供了直接的迭代,并且你展示的代码正在为使事情变得比必要更困难而走出困境。你可以直接用'my_list:'中的项目获得'my_list'项目;';没有必要生成索引。 – 2012-03-31 07:44:09

回答

10

在Python中,for循环遍历一个类似列表的对象,它没有每次都检查的条件语句。为了说明,以下两个循环在功能上是等价的;该while环是for (i=0; i< n; i++) { ... }直接翻译,而for循环是这样做的Python的方式:

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实际上并不返回一个列表,但在使用它的循环时,在功能方面没有区别)

3

这在python中很好,因为range函数会创建一个for循环随后使用的列表。因此len只被调用一次。另外,你不需要额外的0,因为如果没有额外的选项,range从0开始计数。

作为一个方面说明,您通常会想使用xrange,因为它会创建一个延迟评估的生成器。

+0

注意:在python 3范围内创建一个生成器,并且xrange已被删除。 – jamylak 2012-03-31 05:14:13

+2

@jamylak当然,我只是假设早期版本。所有python代码都是为Python 3编写的那一天将是一个美好的一天。 – Squazic 2012-03-31 05:19:21

4

for i in range(len(whatever))是Python的风格差。正如其他人所提到的,直接迭代可通过for element in whatever获得。然而,人们仍然这样做的原因有两个:

  1. 他们是C程序员,并没有围绕直接迭代的思想。

  2. 他们希望在遍历整个列表时修改列表,否则需要索引。如果是这种情况,Pythonic的做法是enumerate函数:for i, element in enumerate(whatever)