优化的方式来计算条件的行数

SOC*_*Ket 3 python

我已经看到计算文件中行数的快速方法是这样做:

n_lines=sum(1 for line in open(myfile))
Run Code Online (Sandbox Code Playgroud)

我想知道是否有可能在sum函数中加入一些条件以便得到类似的东西:

n_lines=sum(1 for line in open(PATHDIFF) if line=='\n' break if line.startswith('#') continue)
Run Code Online (Sandbox Code Playgroud)

先感谢您.

che*_*ner 5

你可以,但有一些限制.您将生成器表达式作为参数传递给sum,并且生成器表达式可以使用带有该if子句的一个表达式.您可以将这样的条件组合在一起:

n_lines=sum(1 for line in open(PATHDIFF)
                if line != '\n' and not line.startswith('#'))
Run Code Online (Sandbox Code Playgroud)

但是,当您点击时,这不会使文件的迭代发生短路newline; 它继续通读文件到最后.为避免这种情况,您可以使用itertools.takewhile,只读取生成器表达式生成的迭代器,直到您读取换行符.

from itertools import takewhile
n_lines = sum(1 for line in takewhile(lambda x: x != '\n',
                                      open(PATHDIFF))
                   if not line.startswith('#'))
Run Code Online (Sandbox Code Playgroud)

您还可以使用itertools.ifilterfalse填充与生成器表达式的condition子句相同的角色.

from itertools import takewhile, ifilterfalse
n_lines = sum(1 for line in ifilterfalse(lambda x: x.startswith('#'),
                                         takewhile(lambda x: x != '\n',
                                                   open(PATHDIFF))))
Run Code Online (Sandbox Code Playgroud)

当然,现在你的代码开始看起来像是用Scheme或Lisp编写的.生成器表达式更容易阅读,但该itertool模块对于构建可以作为不同对象传递的已修改迭代器非常有用.


在另一个主题上,您应始终确保关闭所打开的任何文件,这意味着不要在迭代器中使用匿名文件句柄.最简洁的方法是使用一个with声明:

with open(PATHDIFF) as f:
    n_lines = sum(1 for line in f if line != '\n' and not line.startswith('#'))
Run Code Online (Sandbox Code Playgroud)

其他例子可以类似地修改; 只需更换open(PATHDIFF)f在那里发生.