好的我有一个像这样的文件。
panite,1,1800
ruby,2,100
diamond,0.75,900
emerald,3,250
amethyst,2,50
opal,1,300
sapphire,0.5,750
benitoite,1,2000
malachite,1,60
我们的老师给了我们使用try / except的代码来帮助我们打开文件。我需要打开文件并读取每一行,并使每一行成为一个元组,然后将其放入一个列表中。该列表应该是最后一个数字除以中间数字,然后该值后跟gem的名称(中间数字是gem的克拉)。我遇到的问题是我甚至无法从文件中创建列表。这就是我试图打开它而没有取得多大成功。
def main():
fileFound = False
while not fileFound:
fileName = input('File name containing jewel data: ')
try:
dataFile = open(fileName, "r")
fileFound = True
knapsack()
except:
print ('Could not find that file -- try again')
def knapsack():
list = dataFile.readline()
当我在def knapsack()下将其更改为简单的printstatement时,我确实取得了一些成功,它会打印一些像2 + 2这样简单的东西,但是当我尝试制作一个列表时,它会给我一个除了错误代替。这是我的第一个编程课程,所以对此的任何见解都将受到赞赏。
答案 0 :(得分:1)
def make_jewel(line):
name, carats, price = line.split(",")
return (float(price)/float(carats), name)
def main():
while True:
file_name = input('File name containing jewel data: ')
try:
with open(file_name) as inf:
data = [make_jewel(line) for line in inf]
break
except FileNotFoundError:
print('Could not find that file -- try again')
main()
和一些评论:
except:
没有指定的异常类型(也称为"裸异常"),因为它捕获所有内容而不受欢迎。您应该指定您希望看到的异常类型,并且只处理这些异常;如果你抓住了所有东西并且完全出乎意料的事情失败了(即ComputerOnFireError
!)你将永远不会发现它。
首选使用with
打开文件,因为它可以确保文件始终正常关闭。
在文本模式下打开文件时,可以逐行迭代;这是处理文件的最常用方法。
当你.split()
一个字符串时,你会得到一个字符串列表。在对棋子进行数学运算之前,您必须使用int()
或float()
将它们从字符串转换为数值。
希望有所帮助。
答案 1 :(得分:0)
使用csv模块将行读取为csv行。
import csv
def knapsack(datafile):
output_data = []
csv_reader = csv.reader(datafile, delimiter=',')
for row in csv_reader:
output_data.append(tuple(row))
return output_data
这将为您提供output_data
:
[('panite', '1', '1800'),
('ruby', '2', '100'),
('diamond', '0.75', '900'),
('emerald', '3', '250'),
('amethyst', '2', '50'),
('opal', '1', '300'),
('sapphire', '0.5', '750'),
('benitoite', '1', '2000'),
('malachite', '1', '60')]
这是一个元组列表。这解决了从文件中创建列表的问题。现在,你应该这样做:
int
。output_data
作为参数传递给一个单独的函数,该函数执行您在问题中提到的算术函数。此函数应构建输出列表。对您的代码进行一些评论:
您可以在main函数中定义文件句柄,但不要传递它
到knapsack
函数。但你在背包中引用它
功能,不会给你你想要的。所以你需要通过
datafile
文件句柄作为knapsack
函数的参数。您可以通过以下方式替换main
方法中的这一行:
knapsack()
到
knapsack(datafile)
list
是Python中内置类型的名称。因此,明智的做法是不要将它用作代码中变量的名称。
答案 2 :(得分:0)
你应该:
dataFile
发送到您的knapsack
功能。except
更改为except IOError
,以避免捕获 希望查看的例外情况。关闭文件(考虑使用with
打开文件以避免必须明确关闭它
try:
dataFile = open(fileName, "r")
fileFound = True
knapsack(dataFile)
dataFile.close()
except IOError:
print ('Could not find that file -- try again')
如果您从一开始就使用过except IOError
,那么您会看到此错误:
Traceback (most recent call last):
...
...
NameError: global name 'dataFile' is not defined
knapsack
不知道dataFile
是什么,因此错误。使用try..except
时,始终捕获特定的例外。如果您不知道抛出了哪个错误 - 在python解释器中编写代码之前重现它(例如,尝试打开一个不存在的文件,并注意抛出IOError
)。
在knapsack
中,您需要从readline
更改为readlines
。
def knapsack(dataFile):
list = dataFile.readlines()
您还应考虑使用其他答案中提到的csv
模块来处理数据。
答案 3 :(得分:0)
如果我正确理解您的问题,则例外是因为在dataFile
函数中找不到knapsack
变量。我建议在Python中学习范围规则,或者阅读this关于该主题的优秀章节(或在网上搜索此主题!)。
我推荐的另一件事是不处理所有异常,因为您已经在代码段中显示了这些异常。 Here's why
固定代码可能如下所示:
def main():
fileFound = False
while not fileFound:
fileName = raw_input('File name containing jewel data: ')
try:
dataFile = open(fileName, "r")
fileFound = True
knapsack(dataFile)
except IOError:
print ('Could not find that file -- try again')
def knapsack(dataFile):
list = dataFile.readline() ### Or you want `readlines()` ?
print list ### Print to let you know that it works
# return list ### ???
if __name__ == '__main__':
main()
答案 4 :(得分:0)
def knapsack(dataFile):
with open(dataFile, 'r') as fp:
lines = [line.strip() for line in fp]
data = [tuple(line.split(',')) for line in lines]
return data
您要将背包传递给文件的路径。