【问题标题】:how to make a list of tuples from a file in python如何从python中的文件制作元组列表
【发布时间】:2014-06-07 10:45:54
【问题描述】:

好的,我有一个像这样的文件。

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() 下的简单打印语句时,我实际上已经取得了一点成功,它会打印一些简单的东西,比如 2+2,但是当我尝试制作一个列表时,它给了我除了错误反而。这是我的第一个编程课程,因此我们将不胜感激。

【问题讨论】:

  • 谢谢,我在发布后注意到了,但在我弄清楚之前你已经为我修好了。谢谢!
  • 尝试列表 = dataFile.readlines()。 readline() 只返回一行; readlines() 返回行列表。

标签: python tuples knapsack-problem


【解决方案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()

还有一些cmets:

  • except: 没有指定的异常类型,也称为“裸异常”,因为它捕获所有内容,因此不受欢迎。您应该指定您希望看到的异常类型,并且只处理这些异常;如果你捕捉到了所有东西并且完全出乎意料的失败(即ComputerOnFireError!)你永远不会发现它。

  • 最好使用with 打开文件,因为它可以确保文件始终正确关闭。

  • 当您以文本模式打开文件时,您可以逐行遍历它;这是处理文件的最常用方法。

  • 当你.split() 一个字符串时,你会得到一个字符串列表。在对片段进行数学运算之前,您必须使用int()float() 将它们从字符串转换为数值。

希望对您有所帮助。

【讨论】:

  • 我认为你的代码应该可以工作,但我只想指出你应该让他做功课
【解决方案2】:

使用 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')]

这是一个元组列表。这解决了您从文件中制作列表的问题。现在,你应该这样做:

  • 元组中的数字是字符串。在进行描述中提到的算术运算之前,您需要确保 you convert them to int
  • output_data 作为参数传递给一个单独的函数,该函数执行您在问题中提到的算术函数。这个函数应该建立你的输出列表。

对您的代码的几点说明:

  • 你在main函数中定义了文件句柄,但是不传递 到knapsack 函数。但是你在背包里引用它 不会给你你想要的功能。所以你需要通过 datafile 文件句柄作为 knapsack 函数的参数。您可以通过以下方式替换 main 方法中的这一行:

    knapsack()
    

    knapsack(datafile)
    
  • list 是 Python 中内置类型的名称。所以最好不要在代码中使用它作为变量的名称。

【讨论】:

  • 那么如何将它传递给背包函数呢?
【解决方案3】:

你应该:

  • 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 模块来处理数据。

【讨论】:

  • ... 错误global name 'dataFile' is not defined 发生在Python 2.x 中,因为input 函数试图将输入字符串作为Python 表达式求值;改用raw_input。在 Python 3.x 中,您不会收到该错误。
  • @HughBothwell 不,它没有。查看 knapsack 函数 - dataFile 未定义,因此抛出了 nameError
【解决方案4】:

如果我正确理解您的问题,例外是因为在 knapsack 函数中找不到 dataFile 变量。我建议在 Python 中学习 范围规则 或阅读 this 关于该主题的优秀中肯章节(或在网络上搜索该主题!)。

我建议的另一件事是不要处理所有异常,正如您在 sn-p 中显示的那样。 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()

【讨论】:

    【解决方案5】:

    我会使用 list comprehensions 来做一些更 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
    

    将文件路径传递给背包函数的位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-22
      • 1970-01-01
      • 1970-01-01
      • 2022-11-08
      相关资源
      最近更新 更多