繁体   English   中英

如何从python中的文件制作元组列表

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM