尝试创建一个带有文件名的函数,它返回一个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
我应该使用功能映射,过滤和减少。我曾经问过这个问题并改进了我的答案,但它仍然给我一个错误。以下是该问题的上一版本的链接:
当我运行具有以下内容的文件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)
以下是collatz.py文件的链接:
Collatz.py file link 任何人都可以帮我纠正代码。对python来说相当新,任何帮助都会很棒。
答案 0 :(得分:2)
试试这个:
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()的适用性几乎受到限制 关联运算符,在所有其他情况下,最好写出来 积累循环明确。
因此reduce
为no 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