How To Make A List Of Tuples From A File In Python
Solution 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()
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 (ieComputerOnFireError
!) 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 usingint()
orfloat()
.
Hope that helps.
Solution 2:
Use the csv module to read lines as csv rows.
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
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 thedatafile
file handle as argument to yourknapsack
function. You do this by replacing this line in yourmain
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 yourknapsack
function. - change from
except
toexcept 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 explicitlytry: 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 call last):
...
...
NameError: global name 'dataFile' is not 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:
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()
Solution 5:
I would go with something more Pythonic using list comprehensions
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
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"