[英]how to make a list of tuples from a file in python
好的,我有一个像这样的文件。
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的代码来帮助我们打开文件。 我需要打开文件并阅读每一行,并将每一行设置为一个元组,然后将其放入列表中。 该列表应该是最后一个数字除以中间的数字,然后是该值,然后是宝石的名称(中间的数字是宝石的克拉)。 我遇到的问题是我什至无法从文件中列出列表。 这就是我试图打开它没有太大的成功。
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之类的简单内容,但是当我尝试创建列表时,它却给了我除外错误。 这是我的第一门编程课,因此对此有任何见解将不胜感激。
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
来打开文件with
因为它可以确保始终正确关闭文件。
当您以文本模式打开文件时,可以逐行对其进行遍历; 这是处理文件的最常用方法。
当您使用.split()
字符串时,您将获得一个字符串列表。 在对片段进行数学运算之前,您必须使用int()
或float()
将它们从字符串转换为数值。
希望能有所帮助。
使用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中内置类型的名称。 因此,最好不要在代码中使用它作为变量的名称。
你应该:
dataFile
到您的knapsack
功能。 except
改为except IOError
except
,以避免捕获您确实希望看到的异常。 关闭文件(考虑使用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
模块来处理数据。
如果我正确理解了您的问题,则例外是因为在knapsack
功能中找不到dataFile
变量。 我建议在Python学习范围规则或阅读本的话题优秀到该点章(或搜索网络上的这个话题!)。
我建议的另一件事是不处理代码段中显示的所有异常 。 这就是为什么 。
固定代码可能如下所示:
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()
我会使用列表推导使用更多Pythonic
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
将文件传递到背包功能的位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.