我做这样的事情来总结一行的许多元素:
for line in open(filename, 'r'):
big_list = line.strip().split(delim)
a = sum(int(float(item)) for item in big_list[start:end] if item)
# do some other stuff
这是一个大文件一行一行,有些项目可能会丢失,即等于''。如果我使用上面的语句来计算a,那么脚本变得比没有它时慢得多。有没有办法加快速度?
答案 0 :(得分:0)
正如Padraic评论的那样,使用过滤器修剪掉空字符串,然后删除“if item”:
>>> import timeit
>>> timeit.timeit("sum(int(float(item)) for item in ['','3.4','','','1.0'] if item)",number=10000)
0.04612559381553183
>>> timeit.timeit("sum(int(float(item)) for item in filter(None, ['','3.4','','','1.0']))",number=10000)
0.04827789913997549
>>> sum(int(float(item)) for item in filter(None, ['','3.4','','','1.0']))
4
>>>
在此示例中会产生相反的效果,但可能会在您的上下文中减少。测量看。
答案 1 :(得分:0)
这还没有经过测试,但直观地说,我希望跳过中间浮动转换会有所帮助。你想要获取小数点左边的整数,所以我会尝试通过正则表达式直接执行:
import re
pattern = re.compile("\d+")
然后用正则表达式匹配替换float解析:
sum(int(pattern.search(item).group(0)) for item in big_list[start:end] if item)
如果您不需要保留旧的十进制字符串,您也可以在构建big_list
时动态获取这些字符串。例如,假设我们有一行"6.0,,1.2,3.0,"
。我们可以得到这样的匹配:
delim = ","
pattern = re.compile("(\d+)\.\d+|" + re.escape(delim) + re.escape(delim) + "|$")
该模式的结果将是:['6', '', '1', '3', '']
,然后可以像往常一样进行切片和过滤,而无需浮点解析:
for line in open(filename, 'r'):
big_list = pattern.findall(line)
a = sum(int(item) for item in big_list[start:end] if item)