每个人。
我想说这是我不清楚从哪里开始的第一项任务:
创建一个文本文件(使用编辑器,不一定是Python)包含两个制表符分隔的列,每列包含一个数字然后使用Python读取您创建的文件。对于每行,将第一个数字乘以第二个数字,然后求和所有行的结果。忽略任何不包含的行两个数字列。
到目前为止,我写了几行,但我不确定下一步需要去哪里:
filename = 'path'
def sum_columns(filename):
sum = 0
multiply = 0
with open (filename) as f:
我应该将文件分成两列并创建一个列表,还是应该做其他事情?
提前感谢
这里有一个简短的解决方案:
def sum_columns(filename):
counter = 0
with open(filename) as file:
for line in file:
try:
a, b = [int(x) for x in line.split('t')]
counter += a * b
except ValueError:
continue
return counter
file_name = 'myfile.txt'
print(sum_columns(file_name))
这是很多人(@martineau是第一个)建议在评论中使用的(这也是我刚刚学到的),所以我决定把它放在一个答案中。
基本上,循环在每一行上迭代,并为每一行创建一个由两个整数组成的列表(列表理解只是为了这个,因为否则两个数字都是字符串,如果你尝试将它们相乘,就会产生ValueError
),然后也拆包这两个值,这很好,因为你只需要一个except
,因为抛出的唯一合理错误是ValueError
(要么是因为无法解包,要么是因为字符无法转换为整数),然后将两个值相乘并添加到计数器,在循环结束时返回计数器
根据练习文本,您几乎可以做很多事情。在我看来,最好的方法是这样做:
filename = 'path'
def sum_columns(filename):
sum = 0
multiply = 0
with open (filename) as f:
all_lines = f.readlines()
f.close()
for line in all_lines:
splitted = line.split("t")
sum += int(splitted[0]) * int(splitted[1])
return sum
您将文件的所有行都列在all_lines
中,然后您可以遍历每一行并从选项卡中拆分它们,然后将它们相乘并求和为初始化为0的sum
变量,最后返回该变量。正如其他人所暗示的,你也可以逐行读取文件,而无需将每一行都记在列表中,但如果文件相对较小,你可以选择我的选项。
如果您有这样的文件:
1 2
2 4
4 8
您可以执行以下操作:
from functools import reduce
def is_int(s):
try:
int(s)
return True
except ValueError:
return False
filename = 'path'
def sum_columns(filename):
with open (filename) as f:
lines = f.readlines()
return sum([
reduce(lambda x, y: x * y, map(int,line.split("t")))
for line in lines
if len(list(filter(is_int, line.split("t")))) == 2
])
说明:
在顶部,我定义了一个辅助函数,用于确定字符串是否可以转换为int。这将在以后用于忽略没有2个数字的行。它是基于这个答案
def is_int(s):
try:
int(s)
return True
except ValueError:
return False
然后,我们打开文件,将所有行读取到一个变量中。这不是最有效的,因为它可以在不存储while文件的情况下逐行处理,但是,对于较小的文件,这是可以忽略的。
with open (filename) as f:
lines = f.readlines()
接下来,是执行查询的单个操作,但让我们将其分解:
首先,我们遍历所有行:
for line in lines
接下来,我们只保留由制表符分隔的正好有两个数字的行:
if len(list(filter(is_int, line.split("t")))) == 2
最后,我们将行中的每个数字转换为int
s,并将它们相乘:
reduce(lambda x, y: x * y, map(int,line.split("t")))
然后我们将所有这些相加并返回结果
性能考虑
如果性能是一个问题,您可以实现同样的目的,逐行读取内容,而不是将整个文件拉到一个变量中。它不那么优雅,但更高效:
def sum_columns(filename):
total = 0
with open (filename) as f:
for line in f:
if len(list(filter(is_int, line.split("t")))) != 2:
continue
total += reduce((lambda x, y: x * y), map(int,line.split("t")))
return total
(注意,您仍然需要上面示例中的导入和助手)
input.txt
1 3
2 6
3 7
7 12
8
script.py
with open('input.txt') as f:
total = 0
for line in f:
numbers = line.read().split('t')
try:
line_value = int(numbers[0]) * int(numbers[1])
except IndexError as e:
# the line doesn't contain two numbers
continue
except ValueError as e:
# a value couldn't be converted to a number
continue
total += line_value