how do I convert a data read from a txt file in dictionary format.
Lines from txt file:
A1, 5, Apples
B1, 3, Oranges
Desired output:
{'A1':[5.0,'Apples'], 'B1':[3.0,'Oranges']}
only managed to code these:
fr = open('products.txt','r')
for line in fr.readlines():
code, name, price = line.split(',')
print(line)
fr.close()
You can use comprehension:
result = {line.strip().split(',')[0]: [line.strip().split(',')[1], line.strip().split(',')[2]] for line in open('products.txt','r')}
Or without comprehension:
result = {}
with open('products.txt','r') as fr:
for line in fr:
parts = line.strip().split(',')
result[parts[0]] = [parts[1], parts[2]]
print(result)
my_dict = {}
fr = open('products.txt','r')
for line in fr.readlines():
code, name, price = line.split(',')
my_dict[code] = [name,price]
print(line)
fr.close()
You can create an empty dictionary and update the dictionary for each lines, also strip off the value for price to get rid of residue space after splitting on comma:
data = {}
fr = open('products.txt','r')
for line in fr.readlines():
code, price, name = line.split(',') # price is the middle item, name is last
print(line)
data.update({code:[float(price.strip()), name.strip()]})
fr.close() #Keep this outside the loop
OUTPUT:
{'A1': [5.0, 'Apples'], 'B1': [3.0, 'Oranges']}
You're close, but you've got a few errors and a few missing things...
out_d = {} # init an empty dict
fr = open('products.txt','r')
for line in fr.readlines():
code, price, name = line.split(', ') # not code, name, price
print(line)
out_d[code] = [float(price), name] # adds a new dict entry
fr.close() # gets dedented
print(out_d)
A few things...
(1) according to your input file, you want to split on ', ', not just ','
(2) it looks like the order of your input file is code/price/name not code/name/price
(3) you need to cast the price from string to float
(4) your fr.close() is indented too far. It needs to be dedented.
Also, it's fine to do an open() and close() when you're first starting out. But there is a better way to go, called a context manager, which will automatically do the close() for you. Basically, it would look like this:
out_d = {} # init an empty dict
with open('products.txt','r') as fr: # this creates a context
for line in fr.readlines():
code, price, name = line.split(', ') # not code, name, price
print(line)
out_d[code] = [float(price), name]
# fr.close() -- this line now goes away
print(out_d)
Above, the fr.close() line goes away, because the with open calls close when the with block finishes.
Related
Hey everyone just have an issue with a text file and putting it into a dictionary.
So my code first starts off by gathering data from a website and writes it to a text file. From there I reopen the file and make it into a dictionary to transfer the data from the text to the dictionary. In the while loop, I am getting the error of
key,value = line.split()
ValueError: too many values to unpack (expected 2)
Which I'm not sure why if I'm using the wrong method to write the text file data to the new place in the program of "countryName"
Then once that compiles I want to be able to ask the user to input a country name and it will give the income capita of that country as shown in the print line.
def main():
import requests
webFile = "https://www.cia.gov/library/publications/the-world-factbook/rankorder/rawdata_2004.txt"
data = requests.get(webFile) #connects to the file and gest a response object
with open("capital.txt",'wb') as f:
f.write(data.content) #write the data out to a file – wb used since thecontent from the response object is returned as abinary object.
f.close()
infile = open('capital.txt', 'r')
line = infile.readline()
countryName = {}
while line != "":
key,value = line.split()
countryName[key] = value
line = infile.readline()
infile.close()
userInput = input("Enter a country name: ")
for i in countryName:
while(userInput != 'stop'):
print("The per capita income in",countryName[key], "is",countryName[value])
userInput = input("Enter a country name: ")
main()
each line also has a number in the beginning of it, and some country names have spaces in them, causing split to return longer lists. If you use regex to add in semicolons as delimiters, and trim leading and trailing whitespace, the splitting works properly. This code would go inside the first while loop
line = re.sub(r"(\$)", r";\1", line) # add semicolon before $ sign
line = re.sub(r'^([0-9]+)',r'\1;', line) # add semicolon after first group of numbers
num, key, value = re.split(r';', line) # split with semicolons as delimiters
countryName[key.strip()] = value.strip() # assign key and values after stripping whitespace
Split returns list, not dictionary.
a = 'a b c'
list = a.split() #-> ['a','b','c']
Are you trying to do something like:
import requests
webFile = "https://www.cia.gov/library/publications/the-world-factbook/rankorder/rawdata_2004.txt"
data = requests.get(webFile).text #connects to the file and gest a response object
print(data)
while(1):
name = input('Enter a country name: ')
for a in data.splitlines():
if name.lower() in a.lower():
print(a.split()[-1])
Firstly I use this:
with open(filename) as fp:
for i, line in enumerate(fp):
print(i)
print(line)
if i == index:
break
else:
continue
This makes me able to output each line until ( i ) reaches the amount of the index variable, but this is not all I want, I want to read a file which looks a bit like this :
John|Graham|JOB|AGE
Philip|Jefferson|JOB|AGE
I want to be able to parse this data into corresponding variables, but! I want to be able to specify which line to read from, so that I can read line 1, parse the data from there, and then line 2, but not as in a loop!, which is the important part.
I want to be able to set the variable ( index ) to let's say 2
then line 2 will parse the first segment "Philip" into the variable NAME.
and so on.
I hope you understand!, I have been so frustrated that I have not been able to come up with a solution.
Here's something that should work:
first we need to get all the lines read into a list.
>>> with open('in.txt', 'r') as f:
>>> lines = f.read().splitlines()
now we can index nicely in:
>>> print(lines[0])
John|Graham|JOB|AGE
Okay, now we want to split each line into the data we need.
>>> first = lines[0]
>>> info = first.split('|')
['John', 'Graham', 'JOB', 'AGE']
And then to put everything into a variable:
>>> NAME, LASTNAME, JOB, AGE = info
>>> print(NAME)
John
>>> print(LASTNAME)
Graham
Putting it all together:
with open('in.txt', 'r') as f:
lines = f.read().splitlines()
def get_info(lines, line_num):
line = lines[line_num]
return line.split('|')
NAME, LASTNAME, JOB, AGE = get_info(lines, 0)
print(NAME) # Prints "John"
If you don't want to read in the whole file at once, you can use the same techniques in your script:
with open(filename) as fp:
for i, line in enumerate(fp):
print(i)
print(line)
if i == index:
NAME, LASTNAME, JOB, AGE = line.split('|')
break
You can use a dictionary to allow you to access each line by index:
the_dict = {i:a.strip('\n') for i, a in enumerate(open('filename.txt'))}
Output:
{0: 'John|Graham|JOB|AGE', 1: 'Philip|Jefferson|JOB|AGE'}
I'm trying to figure out how to open up a file and then store it's contents into a dictionary using the Part no. as the key and the other information as the value. So I want it to look something like this:
{Part no.: "Description,Price", 453: "Sperving_Bearing,9900", 1342: "Panametric_Fan,23400",9480: "Converter_Exchange,93859"}
I was able to store the text from the file into a list, but I'm not sure how to assign more than one value to a key. I'm trying to do this without importing any modules. I've been using the basic str methods, list methods and dict methods.
For a txt file like so
453 Sperving_Bearing 9900
1342 Panametric_Fan 23400
9480 Converter_Exchange 93859
You can just do
>>> newDict = {}
>>> with open('testFile.txt', 'r') as f:
for line in f:
splitLine = line.split()
newDict[int(splitLine[0])] = ",".join(splitLine[1:])
>>> newDict
{9480: 'Converter_Exchange,93859', 453: 'Sperving_Bearing,9900', 1342: 'Panametric_Fan,23400'}
You can get rid of the ----... line by just checking if line.startswith('-----').
EDIT - If you are sure that the first two lines contain the same stuff, then you can just do
>>> testDict = {"Part no.": "Description,Price"}
>>> with open('testFile.txt', 'r') as f:
_ = next(f)
_ = next(f)
for line in f:
splitLine = line.split()
testDict[int(splitLine[0])] = ",".join(splitLine[1:])
>>> testDict
{9480: 'Converter_Exchange,93859', 'Part no.': 'Description,Price', 453: 'Sperving_Bearing,9900', 1342: 'Panametric_Fan,23400'}
This adds the first line to the testDict in the code and skips the first two lines and then continues on as normal.
You can read a file into a list of lines like this:
lines = thetextfile.readlines()
You can split a single line by spaces using:
items = somestring.split()
Here's a principial example how to store a list into a dictionary:
>>>mylist = [1, 2, 3]
>>>mydict = {}
>>>mydict['hello'] = mylist
>>>mydict['world'] = [4,5,6]
>>>print(mydict)
Containers like a tuple, list and dictionary can be nested into each other as their items.
To itereate a list you have to use a for statement like this:
for item in somelist:
# do something with the item like printing it
print item
Here's my stab at it, tested on Python 2.x/3.x:
import re
def str2dict(filename="temp.txt"):
results = {}
with open(filename, "r") as cache:
# read file into a list of lines
lines = cache.readlines()
# loop through lines
for line in lines:
# skip lines starting with "--".
if not line.startswith("--"):
# replace random amount of spaces (\s) with tab (\t),
# strip the trailing return (\n), split into list using
# "\t" as the split pattern
line = re.sub("\s\s+", "\t", line).strip().split("\t")
# use first item in list for the key, join remaining list items
# with ", " for the value.
results[line[0]] = ", ".join(line[1:])
return results
print (str2dict("temp.txt"))
You should store the values as a list or a tuple. Something like this:
textname = input("ENter a file")
thetextfile = open(textname,'r')
print("The file has been successfully opened!")
thetextfile = thetextfile.read()
file_s = thetextfile.split()
holder = []
wordlist = {}
for c in file_s:
wordlist[c.split()[0]] = c.split()[1:]
Your file should look like this:
Part no.;Description,Price
453;Sperving_Bearin,9900
1342;Panametric_Fan,23400
9480;Converter_Exchange,93859
Than you just need to add a bit of code:
d = collections.OrderedDict()
reader = csv.reader(open('your_file.txt','r'),delimiter=';')
d = {row[0]:row[1].strip() for row in reader}
for x,y in d.items():
print x
print y
This dictionary is supposed to take the three letter country code of a country, i.e, GRE for great britain, and then take the four consecutive numbers after it as a tuple. it should be something like this:
{GRE:(204,203,112,116)} and continue doing that for every single country in the list. The txt file goes down like so:
Country,Games,Gold,Silver,Bronze
AFG,13,0,0,2
ALG,15,5,2,8
ARG,40,18,24,28
ARM,10,1,2,9
ANZ,2,3,4,5 etc.;
This isn't actually code i just wanted to show it is formatted.
I need my program to skip the first line because it's a header. Here's what my code looks like thus far:
def medals(goldMedals):
infile = open(goldMedals, 'r')
medalDict = {}
for line in infile:
if infile[line] != 0:
key = line[0:3]
value = line[3:].split(',')
medalDict[key] = value
print(medalDict)
infile.close()
return medalDict
medals('GoldMedals.txt')
Your for loop should be like:
next(infile) # Skip the first line
for line in infile:
words = line.split(',')
medalDict[words[0]] = tuple(map(int, words[1:]))
A variation on a theme, I'd convert all the remaining cols to ints, and I'd use a namedtuple:
from collections import namedtuple
with open('file.txt') as fin:
# The first line names the columns
lines = iter(fin)
columns = lines.next().strip().split(',')
row = namedtuple('Row', columns[1:])
results = {}
for line in lines:
columns = line.strip().split(',')
results[columns[0]] = row(*(int(c) for c in columns[1:]))
# Results is now a dict to named tuples
This has the nice feature of 1) skipping the first line and 2) providing both offset and named access to the rows:
# These both work to return the 'Games' column
results['ALG'].Games
results['ALG'][0]
with open('path/to/file') as infile:
answer = {}
for line in infile:
k,v = line.strip().split(',',1)
answer[k] = tuple(int(i) for i in v.split(','))
I think inspectorG4dget's answer is the most readable... but for those playing code golf:
with open('medals.txt', 'r') as infile:
headers = infile.readline()
dict([(i[0], tuple(i[1:])) for i in [list(line.strip().split(',')) for line in infile]])
I'm trying to learn python and I'm doing a problem out of a book but I'm stuck on one question. It asks me to read a file and each line contains an 'a' or a 's' and basically I have a total which is 500. If the line contains an 'a' it would add the amount next to it for example it would say "a 20" and it would add 20 to my total and for s it would subtract that amount. In the end I'm supposed to return the total after it made all the changes. So far I got
def NumFile(file:
infile = open(file,'r')
content = infile.readlines()
infile.close()
add = ('a','A')
subtract = ('s','S')
after that I'm completely lost at how to start this
You need to iterate over the lines of the file. Here is a skeleton implementation:
# ...
with open(filename) as f:
for line in f:
tok = line.split()
op = tok[0]
qty = int(tok[1])
# ...
# ...
This places every operation and quantity into op and qty respectively.
I leave it to you to fill in the blanks (# ...).
A variation might be
f = open('myfile.txt','r')
lines = f.readlines()
for i in lines:
i = i.strip() # removes new line characters
i = i.split() # splits a string by spaces and stores as a list
key = i[0] # an 'a' or an 's'
val = int( i[1] ) # an integer, which you can now add to some other variable
Try adding print statements to see whats going on. The cool thing about python is you can stack multiple commands in a single line. Here is an equivalent code
for i in open('myfile.txt','r').readlines():
i = i.strip().split()
key = i[0]
val = int (i[1])