【问题标题】:Is it alright to call len() in a loop's conditional statement?在循环的条件语句中调用 len() 可以吗?
【发布时间】:2012-03-31 05:01:15
【问题描述】:

在 C 中,这样调用 strlen 被认为是不好的做法:

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

当然,原因是它效率低下,因为它多次“计算”字符串中的字符。

但是,在 Python 中,我经常看到这样的代码:

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

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

【问题讨论】:

  • 我希望您不会看到这样的代码,但出于完全不同的原因:Python 提供了直接迭代,而您展示的代码正在竭尽全力使事情变得比必要的更难.可以直接通过for item in my_list:获取my_list的物品;无需生成索引。

标签: python arrays list


【解决方案1】:

在 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) 在循环开始前被求值,then 它的返回值在循环中使用。换句话说,range(n) 被评估一次(并且只有一次)以获得i 应该采用的值的列表*。

所以在给出的具体示例中,Python 看到for i in range(0, len(list)),评估range(0, len(list))(所以len 被调用一次)并存储输出(它不会再次调用range(或len)) .

(* 在 Python 3.x 中 range 实际上并不返回一个列表,但在 for 循环中使用它时,功能上没有区别)

【讨论】:

    【解决方案2】:

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

    1. 他们是 C 程序员,还没有考虑过直接迭代。

    2. 他们想要在迭代列表时修改列表,或者需要索引。如果是这种情况,Pythonic 的方法是 enumerate 函数:for i, element in enumerate(whatever)

    【讨论】:

    • 如果您希望迭代两个大小相等的列表并将它们的元素成对连接在一起(通过索引匹配)以获得另一个数据结构?
    • 在这种情况下,使用zip
    【解决方案3】:

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

    附带说明,您通常希望使用xrange,因为它创建了一个延迟评估的生成器。

    【讨论】:

    • 注意:在 python 3 中,range 创建了一个生成器,而 xrange 已被删除。
    • @jamylak 当然,我只是假设早期版本。为python 3编写所有python代码的那一天将是美好的一天。
    猜你喜欢
    • 1970-01-01
    • 2020-03-26
    • 2011-02-24
    • 2017-03-10
    • 1970-01-01
    • 2013-08-18
    • 2012-11-09
    • 2021-11-05
    • 2021-03-03
    相关资源
    最近更新 更多