如何将此循环转换为列表理解?

How do I convert this loop into a list comprehension?

我正在尝试将带有嵌套 if 语句的循环转换为 python 中的列表推导式。我想我在列表理解中看不到模式。对于上下文,下面的循环扫描一个名为 ibi_a 的数组,如果它扫描的每个索引的值都小于变量 antStart.

,则增加 rowCount。
rowCount = 0
for row in range(0,len(ibi_a)):
    if ((float(ibi_a[row][timeStampCol])) < antStart):
        rowCount = rowCount+1 #increase rowCount to search for index of antStart

我尝试了以下代码,但没有成功。

rowCount = 0
rowCount = [rowCount+1 for row in range(0,len(ibi_a)) if ((float(ibi_a[row][timeStampCol])) < antStart]

这不是对列表理解的恰当使用。顾名思义,它们用于生成列表;你想要做的是有条件地增加一个变量。坚持你的 for 循环。

你不会增加列表推导中的计数;您只需列出所有符合条件的项目,然后检查列表的长度:

rowCount = len([i for i in ibi_a if float(i[timeStampCol]) < antStart])

顺便说一句,除非你有一些特定的理由来创建一个 range 和一个计数器变量 (row),否则循环 i in ibi_a 是一个更好的主意,即使在你原来的 for 循环中。我会为 i 选择一个更合适的变量名称,但我不知道 "ibi_a" 代表什么或它的元素代表什么。

列表理解用于生成列表,这不是您的 for 循环所做的。如果你愿意,你可以这样做:

rowCount = sum((float(row[timeStampCol]) < antStart) for row in ibi_a)

sum 作为布尔值的计数。

同意 Daniel 的观点,有时可以滥用列表推导式来提高速度。通常的 pretty vs faster,但当然要确定更快你需要计时。 我模拟了一个类似的循环,bench-marked 它同时包含 listcomp 和循环,并且在这种情况下获得了几乎相同的时间。所以我认为你最好把它作为一个循环。 仍然有趣的练习。

import random

l = [random.randrange(1, 100) for i in xrange(10000000)]
antStart = 30
def listcomp():
    rowCount = len([i for i in l if i < antStart])

def usingLoop():
    rowCount = 0
    for i in l:
        if i < antStart:
            rowCount = rowCount+1 

import timeit
print "list comp : ",timeit.timeit(listcomp, number=100)
print "loop : ",timeit.timeit(usingLoop, number=100)

结果是:

Item count : 10^6
list comp :  3.24901601876 s
loop :  3.13708115184 s

Item count : 10^7
list comp :  35.7664684531 s
loop :  31.1584190731 s

在这种特定情况下,您可以看到随着列表的增长,列表分配的开销超过了列表理解通常更快的循环速度。