Getting values from a line in a .txt file with Python - python

I have the difficulty of getting specific values from a line from a .txt file with python. For example from this line:
Packages: Sent = 5, Received = 7, Lost = 0
i would like to get the integer values.
I already tried to use a dictionary in the following way by trying to assign keys and values with a dictionary.
data = {}
with open("file.txt", "rt", errors = "ignore") as file:
lines = file.readlines()
for line in lines:
if "Packages:" in line:
line.split(":")
key1, value1, key2, value2, key3, value3 = line.split(" = ")
data[key1, key2, key3] = value1, value2, value3
print(value1, value2, value3)
I am a beginner, so please excuse me if this problem is trivial.
Thank you!

data = {}
with open("file.txt", "rt", errors = "ignore") as file:
lines = file.readlines()
for line in lines:
if "Packages:" in line:
line_vals=line.replace('Packages:', '').replace('\n','').split(',')
for j in line_vals:
vals=j.split('=') # here you can get each key and value as pair
key=vals[0] #here is your key
value =vals[1] # here is your value

You have to assign the splitted line to th variable
data = {}
with open("file.txt", "rt", errors = "ignore") as file:
lines = file.readlines()
for line in lines:
if "Packages:" in line:
line = line.strip().split(":")
key1, value1, key2, value2, key3, value3 = line.split(" = ")
data[key1, key2, key3] = value1, value2, value3
print(value1, value2, value3)

You're on the correct track, just a few issues in implementation:
data = {}
with open("file.txt", "rt", errors = "ignore") as file:
for line in file:
if "Packages:" in line:
# Remove all spaces in line
line = line.replace(" ", "")
# Remove "Packages:"
line = line.split(":")[1]
# Separate out each <key, value> pair
kv_pairs = line.split(",")
# Fill the dictionary
for kv in kv_pairs:
key, value = kv.split('=')
data[key] = value

Say you have the line
line = 'Packages: Sent = 5, Received = 7, Lost = 0'
To clean up each "word" from line.split(" = "), you may do e.g.
words = [word.strip(' ,:') for word in line.split()]
Note that split() (without argument) splits on whitespace.
If you know that you want e.g. element 3 (the str '5'), do
val = words[3]
You can even convert this to a proper int by
val = int(words[3])
Of course this fails if the str does not actually represent an integer.
Side note
Note that line.split(":") on its own has no effect, as the str line is not mutated (str's are never mutated in Python). This just computes a list of results and then throws it away as you do not assign this result to a variable.

to chek if a var is int you can use this:
i = 12
print(isinstance(i, int)) #True
i = "12"
print(isinstance(i, int)) #False
and in your example you just need to do it:
lines = ["Packages: Sent = 5, Received = 7, Lost = 0"]
data = {}
linenumber = 1
for line in lines:
line = line.split(": ")[1]
col = line.split(",")
dic = {}
for item in col:
item = item.split(" = ")
dic.update({item[0]:item[1]})
data.update({"1":dic})
linenumber += 1
print(data)
and if you need to check only values that is interger you should do it:
lines = ["Packages: Sent = 5, Received = oi, Lost = 0"]
data = {}
error=[]
linenumber = 1
for line in lines:
line = line.split(": ")[1]
col = line.split(",")
dic = {}
for item in col:
item = item.split(" = ")
try:
if isinstance(int(item[1]), int):
dic.update({item[0]:item[1]})
except:
error.add("Cannot convert str to int in line " + linenumber )
# nothing to do
data.update({"1":dic})
linenumber += 1
print(data)

Related

Why does this code get a "ValueError: too many values to unpack (expected 2)" error?

I am doing this for my teacher and most of this code works great. Only at the very end (" lastf.write(key, value)") I get the error "ValueError: too many values to unpack (expected 2)"
import json
# --1--
file = open("C:\\Users\\PycharmProjects\\p5.txt", 'w')
for i in range (4):
a = input("enter a sentence")
file.write(a+"\n")
file.close()
file2 = open("C:\\Users\\PycharmProjects\\p5.txt", 'r')
lines = file2.read().splitlines()
last_line = lines[-1]
print(last_line)
# --2--
def splitname():
textf = open("C:\\Users\\PycharmProjects\\linuxEtcPassword.txt", 'r')
ditailsd = {}
for line in textf:
newsplit = line.replace('\n', ' ').split(":")
nv = {newsplit[0]: newsplit[2]}
ditailsd.update(nv)
dict1 = sorted(ditailsd.keys())
conlst = {dict1[d]: dict1[d + 1] for d in range(0, len(dict1)-1, 2)}
print(conlst)
lastf = open("C:\\Users\\PycharmProjects\\linuxEtcPassword1.txt", 'w')
for key, value in conlst:
lastf.write(key, value)
file.close()
splitname()
file.write('takes an argument /n will add a new line')
youre trying to write two items, are you trying to write something like,
key1, value1,
key2, value2 ?
you can use something like file.write(f"{key}:{value}\n")

Read dictionary from file into original lists

I have one nested list, and one list for "numbers"
test_keys = [["tobbe", "kalle"],["karl", "Clara"],["tobbe"],["tank"]]
test_values = ['123', '234','345','456']
res = {}
for key in test_keys:
for value in test_values:
res[value] = key
test_values.remove(value)
break
with open("myfile.txt", 'w') as f:
for key, value in res.items():
f.write('%s;%s;\n' % (key, value))
This provides the file
123;['tobbe', 'kalle'];
234;['karl', 'Clara'];
345;['finis'];
456;['tank'];
now I want to load the data back into the a dictionary without the ";" and later on back into the corresponding lists.
Try this:
res = {}
with open("myfile.txt") as file:
for line in file:
chunks = line.split(';')
names = chunks[1][1:-1].split(', ')
res[chunks[0]] = [name[1:-1] for name in names]
print(res)
test_keys = []
test_values = []
for key in res:
test_keys.append(key)
test_values.append(res[key])
print(test_keys)
print(test_values)

trying to create a dictionary from a text file but

so, I have text file (a paragraph) and I need to read the file and create a dictionary containing each different word from the file as a key and the corresponding value for each key will be an integer showing the frequency of the word in the text file.
an example of what the dictionary should look like:
{'and':2, 'all':1, 'be':1, 'is':3} etc.
so far I have this,
def create_word_frequency_dictionary () :
filename = 'dictionary.txt'
infile = open(filename, 'r')
line = infile.readline()
my_dictionary = {}
frequency = 0
while line != '' :
row = line.lower()
word_list = row.split()
print(word_list)
print (word_list[0])
words = word_list[0]
my_dictionary[words] = frequency+1
line = infile.readline()
infile.close()
print (my_dictionary)
create_word_frequency_dictionary()
any help would be appreciated thanks.
Documentation defines collections module as "High-performance container datatypes". Consider using collections.Counter instead of re-inventing the wheel.
from collections import Counter
filename = 'dictionary.txt'
infile = open(filename, 'r')
text = str(infile.read())
print(Counter(text.split()))
Update:
Okay, I fixed your code and now it works, but Counter is still a better option:
def create_word_frequency_dictionary () :
filename = 'dictionary.txt'
infile = open(filename, 'r')
lines = infile.readlines()
my_dictionary = {}
for line in lines:
row = str(line.lower())
for word in row.split():
if word in my_dictionary:
my_dictionary[word] = my_dictionary[word] + 1
else:
my_dictionary[word] = 1
infile.close()
print (my_dictionary)
create_word_frequency_dictionary()
If you are not using version of python which has Counter:
>>> import collections
>>> words = ["a", "b", "a", "c"]
>>> word_frequency = collections.defaultdict(int)
>>> for w in words:
... word_frequency[w] += 1
...
>>> print word_frequency
defaultdict(<type 'int'>, {'a': 2, 'c': 1, 'b': 1})
Just replace my_dictionary[words] = frequency+1 with my_dictionary[words] = my_dictionary[words]+1.

creating a dictionary in python

I have a file with the following format.
>abc
qqqwqwqwewrrefee
eededededededded
dededededededd
>bcd
swswswswswswswws
wswswsddewewewew
wrwwewedsddfrrfe
>fgv
wewewewewewewewew
wewewewewewewxxee
wwewewewe
I was trying to create a dictionary with (>abc,>bcd,>fgv) as keys and the string below them as values. I could extract the keys but confused about updating the values. help me pls.
file2 = open("ref.txt",'r')
for line in file2.readlines():
if ">" in line:
print (line)
Not sure what you mean about "updating" the values, but try this:
mydict=[]
with open("ref.txt", "r") as file2:
current = None
for line in file2.readlines():
if line[0] == ">":
current = line[1:-1]
mydict[current] = ""
elif current:
mydict[current] += line # use line[:-1] if you don't want the '\n'
In [2]: mydict
Out[2]: {'abc': 'qqqwqwqwewrrefee\neededededededded\ndededededededd\n',
'bcd': 'swswswswswswswws\nwswswsddewewewew\nwrwewedsddfrrfe\n',
'fgv': 'wewewewewewewewew\nwewewewewewewxxee\nwwewewewe\n'}
When you get a line value with the '>' in it, save the line in a variable. When you read a line without the '>' in it, add it to a dictionary entry keyed by the previously saved variable.
key = None
dict = {}
for line in file2.readlines():
if ">" in line:
key = line
dict[key] = '' # Initialise dictionary entry
elif key is not None:
dict[key] += line # Append to dictionary entry
dictionary = {}
with open("file.txt","r") as r:
for line in r.readlines():
if ">" in line:
key = line[1:].strip()
dictionary[key] = ""
else:
dictionary[key] += line
print(dictionary)
d={}
key=''
file2 = open("ref.txt",'r')
for line in file2.readlines():
if line.startswith('>'):
key=line.strip()
d[key]=[]
continue
d[key].append(line.strip())
file.close()
I have not tested the above code, but it should work

Finding a line in a file then reading next few lines in Python

I have a plain text file with the following data:
id=1
name=Scott
occupation=Truck driver
age=23
id=2
name=Dave
occupation=Waiter
age=16
id=3
name=Susan
occupation=Computer programmer
age=29
I'm trying to work out the best way to get to any point in the file given an id string, then grab the rows underneath to extract the data for use in my program. I can do something like:
def get_person_by_id(id):
file = open('rooms', 'r')
for line in file:
if ("id=" + id) in line:
print(id + " found")
But I'm not sure how I can now go through the next bunch of lines and do line.split("=") or similar to extract the info (put into a list or dict or whatever) that I can use my program. Any pointers?
One option would be to load the entire thing into memory, which would save you from reading the file every time:
with open('rooms') as f:
chunks = f.read().split('\n\n')
people_by_id = {}
for chunk in chunks:
data = dict(row.split('=', 1) for row in chunk.split('\n'))
people_by_id[data['id']] = data
del data['id']
def get_person_by_id(id):
return people_by_id.get(id)
How about exiting from a for loop after finding the correct line:
def get_person_by_id(id):
file = open('rooms', 'r')
for line in file:
if ("id=" + id) in line:
print(id + " found")
break
#now you can continue processing your file:
next_line = file.readline()
Maybe:
d = dict()
with open(filename) as f:
for line in f:
k,v = line.split('=')
if 'id=' in line:
d[v] = {}
d[d.keys()[-1]][k] = v
And here is an iterative solution.
objects = []
current_object = None
with open("info.txt", "rb") as f:
for line in f:
line = line.strip("\r\n")
if not line:
current_object = None
continue
if current_object is None:
current_object = {}
objects.append(current_object)
key,_,value = line.partition('=')
current_object[key] = value
print objects
Another example of an iterative parser:
from itertools import takewhile
def entries(f):
e = {}
def read_one():
one = {}
for line in takewhile(lambda x: '=' in x, f):
key, val = line.strip().split('=')
one[key] = val
return one
while True:
one = read_one()
if not one:
break
else:
e[one.pop('id')] = one
return e
Example:
>>> with open('data.txt') as f:
..: print entries(f)['2']
{'age': '16', 'occupation': 'Waiter', 'name': 'Dave'}
Get all the person's attributes and values (i.e. id, name, occupation, age, etc..), till you find
an empy line.
def get_person_by_id(id):
person = {}
file = open('rooms', 'r')
for line in file:
if found == True:
if line.strip():
attr, value = line.split("="):
else:
return person
elif ("id=" + id) in line:
print(id + " found")
found = True
attr, value = line.split("=")
person[attr] = value
return person
This solution is a bit more forgiving of empty lines within records.
def read_persons(it):
person = dict()
for l in it:
try:
k, v = l.strip('\n').split('=', 1)
except ValueError:
pass
else:
if k == 'id': # New record
if person:
yield person
person = dict()
person[k] = v
if person:
yield person

Categories

Resources