如何将此循环转换为列表理解?
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
在这种特定情况下,您可以看到随着列表的增长,列表分配的开销超过了列表理解通常更快的循环速度。
我正在尝试将带有嵌套 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
在这种特定情况下,您可以看到随着列表的增长,列表分配的开销超过了列表理解通常更快的循环速度。