【问题标题】:Counting non blank and sum of length of lines in python在python中计算非空白和行长总和
【发布时间】:2015-04-08 18:36:28
【问题描述】:

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

def code_metric(file_name):
    with open(file_name) as f:
        lines = f.read().splitlines()
    char_count = sum(map(len,(map(str.strip,filter(None,lines)))))
    return len(lines), char_count

我应该为此使用函数映射、过滤和归约。我之前曾问过这个问题并改进了我的答案,但它仍然给我一个错误。这是问题的先前版本的链接:

Old program code

当我运行具有以下内容的文件 cmtest.py 时

import prompt,math

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

结果应该是

(3,85)

但我不断得到:

(4,85)

另一个要测试的文件 colltaz.py 例如:

结果应该是:

(73, 2856)

我不断得到的一点:

(59, 2796)

这里是 collat​​z.py 文件的链接:

Collatz.py file link 任何人都可以帮助我更正代码。我对 python 相当陌生,任何帮助都会很棒。

【问题讨论】:

    标签: function python-3.x functional-programming tuples


    【解决方案1】:

    试试这个:

    def code_metric(file_name):
        with open(file_name) as f:
            lines = [line.rstrip() for line in f.readlines()]
        nonblanklines = [line for line in lines if line]
        return len(nonblanklines), sum(len(line) for line in nonblanklines)
    

    例子:

    >>> code_metric('collatz.py')
    (73, 2856)
    
    >>> code_metric('cmtest.py')
    (3, 85)
    

    讨论

    我只能通过删除行尾的尾随换行符和尾随空格来实现collatz.py 的预期结果。这是在这一步完成的:

    lines = [line.rstrip() for line in f.readlines()]
    

    下一步是删除空行:

    nonblanklines = [line for line in lines if line]
    

    我们要返回非空行的数量:

    len(nonblanklines)
    

    我们还想返回非空行的字符总数:

    sum(len(line) for line in nonblanklines)
    

    大文件的替代版本

    此版本不需要一次将文件全部保存在内存中:

    def code_metric2(file_name):
        with open(file_name) as f:
            lengths = [len(line) for line in (line.rstrip() for line in f.readlines()) if line]
        return len(lengths), sum(lengths)
    

    使用reduce 的替代版本

    Python 的创建者 Guido van Rossum,wrote this 关于 reduce 内置函数:

    所以现在减少()。这其实是我一直最讨厌的, 因为,除了一些涉及 + 或 * 的例子之外,几乎每次 我看到一个带有非平凡函数参数的 reduce() 调用,我需要 拿起笔和纸,画出实际输入的内容 在我理解 reduce() 应该做什么之前,函数。所以 在我看来,reduce() 的适用性几乎仅限于 关联运算符,在所有其他情况下最好写出 明确的累积循环。

    因此reduceno longer a builtin in python3。不过,为了兼容性,它在functools 模块中仍然可用。下面的代码如何使用reduce 来解决这个特定问题:

    from functools import reduce
    
    def code_metric3(file_name):
        with open(file_name) as f:
            lengths = [len(line) for line in (line.rstrip() for line in f.readlines()) if line]
        return len(lengths), reduce(lambda x, y: x+y, lengths)
    

    这是另一个使用reduce的版本:

    from functools import reduce
    def code_metric4(file_name):
        def fn(prior, line):
            nlines, length = prior
            line = line.rstrip()
            if line:
                nlines += 1
                length += len(line)
            return nlines, length
        with open(file_name) as f:
            nlines, length = reduce(fn, f.readlines(), (0, 0))
        return nlines, length
    

    【讨论】:

    • @John1024- 谢谢..它似乎适用于该特定文件,但不适用于任何其他文件。它总是给我错误的结果。
    • @BoJaNgLeS 请给我一个此类文件的示例以及 (a) 您获得的输出和 (b) 您认为应该获得的输出。
    • @BoJaNgLeS 经过一些测试,诀窍似乎是在进行计数之前从行中删除尾随换行符和任何尾随空格。我已经用适用于这两个示例的代码更新了答案。
    • @BoJaNgLeS 我添加了一个部分来展示如何使用reduce。它还讨论了python3中reduce的当前状态。
    • @BoJaNgLeS 我添加了另一个更高级使用 reduce 的示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    • 2020-09-04
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多