【问题标题】:counting non-empty lines and sum of lengths of those lines in python在python中计算非空行和这些行的长度总和
【发布时间】:2015-02-07 22:52:59
【问题描述】:

我正在尝试创建一个函数,该函数采用文件名并返回一个 2 元组,其中包含该程序中非空行的数量以及所有这些行的长度之和。这是我目前的程序:

def code_metric(file):
    with open(file, 'r') as f: 
        lines = len(list(filter(lambda x: x.strip(), f)))
        num_chars = sum(map(lambda l: len(re.sub('\s', '', l)), f))

    return(lines, num_chars)

如果我这样做,我得到的结果是:

if __name__=="__main__":
print(code_metric('cmtest.py'))

(3, 0)

什么时候应该:

(3,85)

还有没有更好的方法来使用函数 map、filter 和 reduce 来找到行长度的总和?我为第一部分做了,但无法弄清楚后半部分。我对 python 有点陌生,所以任何帮助都会很棒。

这里是名为 cmtest.py 的测试文件:

import prompt,math

x = prompt.for_int('Enter x')
print(x,'!=',math.factorial(x),sep='')

First line has 18 characters (including white space)
Second line has 29 characters
Third line has 38 characters

[(1, 18), (1, 29), (1, 38)]

行数为 85 个字符,包括空格。对不起,我误读了这个问题。每行的总长度也应包括空格。

【问题讨论】:

  • 你确定在数字符数时没有数行中的空格吗?
  • 您正在执行两次迭代(每次打开文件并循环遍历行)-如果您想提高效率,为什么不将两个操作合并到一次迭代中?
  • @Aradmey- 我相当肯定。它只差 1。这就是为什么我似乎无法弄清楚为什么?我
  • @alfasin- 我不知道该怎么做。关于如何做的任何建议?
  • 您正在计算所有非空格字符的字符。因此,如果有一些你没有看到的空白——最后是一个制表符或一个额外的 CR——你的计数可能不是你所期望的。在for line in f: 之后,您可以添加print(repr(line)) 以查看实际情况。 (PS:你可能对isspace方法感兴趣。)

标签: function python-3.x tuples lambda


【解决方案1】:

一个相当简单的方法是构建一个生成器来去除尾随空格,然后 enumerate 在其上(起始值为 1)filter 取出空白行,并依次对每行的长度求和,例如:

def code_metric(filename):
    line_count = char_count = 0
    with open(filename) as fin:
        stripped = (line.rstrip() for line in fin)
        for line_count, line in enumerate(filter(None, stripped), 1):
            char_count += len(line)
    return line_count, char_count

print(code_metric('cmtest.py'))
# (3, 85)

【讨论】:

  • 我理解,但它必须使用函数式编程风格,使用函数式映射、过滤器和归约来实现。这是为了学习目的。
  • @BoJaNgLeS 可行 - 尽管可读性不强/不推荐......给我一个莫':p
  • @JonClements- 有运气吗??
【解决方案2】:

为了计算行数,也许这段代码更简洁:

with open(file) as f:
    lines = len(file.readlines())

对于程序的第二部分,如果您打算只计算非空字符,那么您忘记删除 '\t' 和 '\n'。如果是这样的话

with open(file) as f:
    num_chars = len(re.sub('\s', '', f.read()))

有些人建议您在一个循环中完成这两件事。这很好,但是如果你把它们分开,你可以把它们变成不同的功能,这样它们就有了更多的可重用性。除非您正在处理巨大的文件(或执行此代码数百万次),否则在性能方面应该无关紧要。

【讨论】:

  • 如果我使用with open(file) as f: num_chars = sum(map(lambda l: len(re.sub('\s', '', l)), f)) 我得到(3,0) 而不是(3,85)
  • 你的线条看起来怎么样?我有一个带有abc d a ef oo o 行的文件。运行后,我得到num_chars 等于 10。
  • Almeda- 问题中有一个测试文件。这是正在测试的文件,行看起来与示例中显示的完全一样。
  • 该文件上的非空字符数实际上是 200。这就是该行返回的内容。不过,我把它改成了我现在才意识到的更好的东西。
  • 仍然返回(3,0)
猜你喜欢
  • 2015-04-08
  • 2015-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多