Skip to content Skip to sidebar Skip to footer

How To Make A List Of Tuples From A File In Python

Ok I have a file like that looks like this. 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 Our t

Solution 1:

defmake_jewel(line):
    name, carats, price = line.split(",")
    return (float(price)/float(carats), name)

defmain():
    whileTrue:
        file_name = input('File name containing jewel data: ')
        try:
            withopen(file_name) as inf:
                data = [make_jewel(line) for line in inf]
            breakexcept FileNotFoundError:
            print('Could not find that file -- try again')

main()

and some comments:

  • except: without a specified exception-type, also known as a "bare exception", is frowned on because it catches everything. You should specify the type of exceptions you expect to see, and only handle those; if you catch everything and something totally unexpected fails (ie ComputerOnFireError !) you will never find out about it.

  • opening a file using with is preferred because it ensures the file will always get closed properly.

  • when you open a file in text mode, you can iterate over it line-by-line; this is the most common way to process a file.

  • when you .split() a string, you get a list of strings back. Before doing math on the pieces you have to convert them from a string to a numeric value using int() or float().

Hope that helps.

Solution 2:

Use the csv module to read lines as csv rows.

import csv

defknapsack(datafile):
    output_data = []
    csv_reader = csv.reader(datafile, delimiter=',')
    for row in csv_reader:
        output_data.append(tuple(row))
    return output_data

This will give you output_data as:

[('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')]

which is a list of tuples. This solves your problem of making a list from the file. Now, you should do:

  • The numerals in the tuples are strings. You need to make sure you convert them to int before you do the arithmetic operations as you mention in your description.
  • Pass output_data as an argument to a separate function that does the arithmetic functions you mentioned in your question. This function should build your output list.

A few remarks on your code:

  • You define the file handle in the main function, but do not pass it to the knapsack function. But you reference it in the knapsack function which will not give you what you want. So you need to pass the datafile file handle as argument to your knapsack function. You do this by replacing this line in your main method from:

    knapsack()
    

    to

    knapsack(datafile)
    
  • list is the name of a built in type in Python. So it is wise not to use it as the name of a variable in your code.

Solution 3:

You should:

  • send dataFile to your knapsack function.
  • change from except to except IOError to avoid catching exceptions you do want to see.
  • close the file (consider using with to open the file to avoid having to close it explicitly

    try:
        dataFile = open(fileName, "r")
        fileFound = True
        knapsack(dataFile)
        dataFile.close()
    except IOError:
        print ('Could not find that file -- try again')
    

If you had used except IOError from the start of, you would have seen this error:

Traceback (most recent calllast):
  ...
  ...
NameError: global name 'dataFile'isnot defined

knapsack does not know what dataFile is, hence the error. Always catch specific exceptions when using try..except. If you don't know which error is thrown - reproduce it before you write the code in the python interpreter (e.g try to open a file that doesn't exists, and notice that IOError is thrown).

In knapsack you need to change from readline to readlines.

def knapsack(dataFile):
    list = dataFile.readlines()

You should also consider to use the csv module as mentioned in the other answer to handle the data.

Solution 4:

If I understand your question correctly, the exception is because dataFile variable is not found inside the knapsack function. I'd suggest learning scoping rules in Python or read this excellent to-the-point chapter on the topic (or search for this topic on the Web!).

The other thing I'd recommend is not to handle all exceptions as you've shown in your snippet. Here's why.

The fixed code could look something like this:

defmain():
    fileFound = Falsewhilenot 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')

defknapsack(dataFile):
    list = dataFile.readline() ### Or you want `readlines()` ?printlist### Print to let you know that it works# return list ### ???if __name__ == '__main__':
    main()

Solution 5:

I would go with something more Pythonic using list comprehensions

defknapsack(dataFile):
    withopen(dataFile, 'r') as fp:
        lines = [line.strip() for line in fp]

    data = [tuple(line.split(',')) for line in lines]

    return data

Where you are passing to your knapsack function the path to your file.

Post a Comment for "How To Make A List Of Tuples From A File In Python"