Python program treating dictionary like a string - python

I set up a dictionary, and filled it from a file, like so:
filedusers = {} # cheap way to keep track of users, not for production
FILE = open(r"G:\School\CS442\users.txt", "r")
filedusers = ast.literal_eval("\"{" + FILE.readline().strip() + "}\"")
FILE.close()
then later I did a test on it, like this:
if not filedusers.get(words[0]):
where words[0] is a string for a username, but I get the following error:
'str' object has no attribute 'get'
but I verified already that after the FILE.close() I had a dictionary, and it had the correct values in it.
Any idea what's going on?

literal_eval takes a string, and converts it into a python object. So, the following is true...
ast.literal_eval('{"a" : 1}')
>> {'a' : 1}
However, you are adding in some quotations that aren't needed. If your file simply contained an empty dictionary ({}), then the string you create would look like this...
ast.literal_eval('"{}"') # The quotes that are here make it return the string "{}"
>> '{}'
So, the solution would be to change the line to...
ast.literal_eval("{" + FILE.readline().strip() + "}")
...or...
ast.literal_eval(FILE.readline().strip())
..depending on your file layout. Otherwise, literal_eval sees your string as an ACTUAL string because of the quotes.

>>> import ast
>>> username = "asd: '123'"
>>> filedusers = ast.literal_eval("\"{" + username + "}\"")
>>> print filedusers, type(filedusers)
{asd} <type 'str'>
You don't have a dictionary, it just looks like one. You have a string.

Python is dynamically typed: it does not require you to define variables as a specific type. And it lets you define variables implicitly. What you are doing is defining filedusers as a dictionary, and then redefining it as a string by assigning the result of ast.literal_eval to it.
EDIT: You need to remove those quotes. ast.literal_eval('"{}"') evaluates to a string. ast.literal_eval('{}') evaluates to a dictionary.

Related

Convert string of lists into list of lists in Python

I'm trying to convert a list of lists passed as string to nested list in python-3.7.5 and I'm missing something. I tried ast but it seems to be throwing an encoding error.
Example:
#!/usr/bin/env python
import ast
sample="[1abcd245,2bcdasdf,3jakdshfkh234234],[234asdfmnkk234]"
print(ast.literal_eval(sample))
ERROR:
return compile(source, filename, mode, PyCF_ONLY_AST)
File "<unknown>", line 1
[1abcd245,2bcdasdf,3jakdshfkh234234],[234asdfmnkk234]
Required output:
[[1abcd245,2bcdasdf,3jakdshfkh234234],[234asdfmnkk234]]
Any suggestions?
You may use the eval() function here, after making two changes to your starting string:
Wrap each list item in double quotes
Wrap the entire input in [...] to make it a formal 2D list
sample = "[1abcd245,2bcdasdf,3jakdshfkh234234],[234asdfmnkk234]"
sample = '[' + re.sub(r'(\w+)', r'"\1"', sample) + ']'
list = eval(sample)
print(list)
This prints:
[['1abcd245', '2bcdasdf', '3jakdshfkh234234'], ['234asdfmnkk234']]
I think the issue is that literal_eval is unable to parse the strings within the sample you provide. I was able to get the output you wanted by adding a triple quote to surround the sample string, adding quotes to each string within the lists and adding an extra set of brackets:
import ast
sample="""[["1abcd245","2bcdasdf","3jakdshfkh234234"],["234asdfmnkk234"]]"""
print(ast.literal_eval(sample))
In the case you cannot change the input I would recommend using the json library:
import json
json.loads(sample)
Which on my machine gets the desired result!
you can try this:
sample="[1abcd245,2bcdasdf,3jakdshfkh234234],[234asdfmnkk234]"
l1 = []
for item in sample.split(","):
if item.startswith('['):
l1.append([])
l1[-1].append(item[1:])
elif item.endswith(']'):
l1[-1].append(item[:-2])
else:
l1[-1].append(item)
print(l1)

how to print after the keyword from python?

i have following string in python
b'{"personId":"65a83de6-b512-4410-81d2-ada57f18112a","persistedFaceIds":["792b31df-403f-4378-911b-8c06c06be8fa"],"name":"waqas"}'
I want to print the all alphabet next to keyword "name" such that my output should be
waqas
Note the waqas can be changed to any number so i want print any name next to keyword name using string operation or regex?
First you need to decode the string since it is binary b. Then use literal eval to make the dictionary, then you can access by key
>>> s = b'{"personId":"65a83de6-b512-4410-81d2-ada57f18112a","persistedFaceIds":["792b31df-403f-4378-911b-8c06c06be8fa"],"name":"waqas"}'
>>> import ast
>>> ast.literal_eval(s.decode())['name']
'waqas'
It is likely you should be reading your data into your program in a different manner than you are doing now.
If I assume your data is inside a JSON file, try something like the following, using the built-in json module:
import json
with open(filename) as fp:
data = json.load(fp)
print(data['name'])
if you want a more algorithmic way to extract the value of name:
s = b'{"personId":"65a83de6-b512-4410-81d2-ada57f18112a",\
"persistedFaceIds":["792b31df-403f-4378-911b-8c06c06be8fa"],\
"name":"waqas"}'
s = s.decode("utf-8")
key = '"name":"'
start = s.find(key) + len(key)
stop = s.find('"', start + 1)
extracted_string = s[start : stop]
print(extracted_string)
output
waqas
You can convert the string into a dictionary with json.loads()
import json
mystring = b'{"personId":"65a83de6-b512-4410-81d2-ada57f18112a","persistedFaceIds":["792b31df-403f-4378-911b-8c06c06be8fa"],"name":"waqas"}'
mydict = json.loads(mystring)
print(mydict["name"])
# output 'waqas'
First you need to convert the string into a proper JSON Format by removing b from the string using substring in python suppose you have a variable x :
import json
x = x[1:];
dict = json.loads(x) //convert JSON string into dictionary
print(dict["name"])

Replacing strings in a .data file

I have a seemingly simple problem. I have a dataset: archive.ics.uci.edu/ml/machine-learning-databases/acute/diagnosis.data
and I want to replace the "no"s to "0"s and "yes" to "1"s
I have tried this code:
fString = open("diagnosis.data","r")
fBool = open("diagnosis1.txt","w")
for line in fString:
line.replace("no","0")
line.replace("yes","1")
fBool.write(line)
fString.close()
fBool.close()
The only thing that happened is that the last yes/no gets an ਍ഀ added. I dont know why it's not working.
Since replace returns the modified string you need to assign it. The original is left untouched. I guess you need:
with open("diagnosis.data", "r") as fString, open("diagnosis1.txt", "w") as fBool:
for line in fString:
nline = line.replace("no", "0")
nline = nline.replace("yes", "1")
fBool.write(nline)
Your issue may be that open() doesn't return a list of strings (or some other iterable type), and therefore you can't do for line in fString:, because that will not yield strings which you can then .replace().
Instead you need to do something like:
fString = open("diagnosis.data","r")
lines = fString.read().split('\n')
fBool = open("diagnosis1.txt","w")
for line in lines:
newLine = line.replace("no","0")
newLine = newLine.replace("yes","1")
fBool.write(newLine)
fString.close()
fBool.close()
This approach gets a list of strings, each of which is a line of a file, and the iterates through that. You need to make sure you use the .replace() method correctly as well, because it returns the new string, but doesn't modify the original string.
The .replace string method returns the string with the replaced parameters but it doesnt change the object so:
>>> k="lolo"
>>> k.replace('l','k')
'koko'
>>> k
'lolo'
>>> k=k.replace('l','k')
>>> k
'koko'
What you want is:
line=line.replace("no","0")
or with an auxiliar variable:
aux=line.replace("no","0").replace("yes","1")

How to put a variable in text file?

So i'm trying to insert a variable inside a text file and i've defined them as shown below:
for filename in os.listdir("/home/gyanender/Desktop/s1d_gyanender"):
if filename.endswith("_s1d_A.fits"):
df = pd.DataFrame.from_dict(SN_dic,orient='index')
df = df.mean()
out_name = s1d_header['OBJECT'] +'-' + s1d_header['DATE-OBS'] +'.ares'
mine_opt = '/home/gyanender/bin/ARES/mine.opt'
file_opt=open(mine_opt,'w')
file_opt.writelines(("specfits=filename","\n","fileout=out_name","\n","rejt=df"))
file_opt.close()
So in the end what i got is something like this, i got name of the variables in the text but what i want is the values of those variables in my text file as i've to give that file as an input to another code.
specfits='filename'
fileout='out_name'
rejt=df
As
filename = HARPS.2016-04-01T09:44:43.034_s1d_A.fits
out_name = Moon-2016-04-01T09:44:43.034.ares
rejt = 166.6 (As the values of df is 166.6)
So my ideal file should look like something like this:
specfits='HARPS.2016-04-01T09:44:43.034_s1d_A.fits'
fileout='Moon-2016-04-01T09:44:43.034.ares'
rejt= 166.6
So can someone tell me where i'm making the mistake?
You're doing
file_opt.writelines(("specfits=filename","\n","fileout=out_name","\n","rejt=df"))
Note that you're actually printing the string "specfits=filename" to a the file. There's nothing here to tell the code that that's not what you want it to print.
I think what you want is to substitute the variable name for the variable itself. This can be done using string formatting. Assuming python 3:
file_opt.writelines(("specfits={}".format(filename), "\n", "fileout={}".format(out_name), "\n", "rejt={}".format(df)))
Here, the {} in your string is replaced by whatever you give as an argument to the format() function.
If you want single-quotes around the values you can just put them in the string you're printing out, e.g. "specfits='{}'"
Don't try to invent the wheel, choose some storage method and use it.
This example uses json:
import json
data = { # create a dict with the data
'specfits': specfits,
'fileout': fileout,
'rejt': rejt,
}
with open(mine_opt, 'w') as file_opt:
json.dump(data, file_opt)
Then reading it will be very easy!
with open(mine_opt) as file_opt:
data = json.load(file_opt)
print(data['specfits']) # will print HARPS.2016-04-01T09:44:43.034_s1d_A.fits

convert string value to dictionary from pickled

val = "{t:30, f:50}"
is a string value and i need to convert it into dictionary other than the conventional method of using val.split(',') and then remove brackets and take out key and bind value to it and convert it in dictionary. Can anyone suggest any better approach towards it. PLz do care that even there is no quotes in strings in keys(t and s). Got some values from db.Already tried json loads or dumps.
import re
x="{t:30, f:50}"
y=re.findall(r"([^ {,]*):([^ {,]*)[,}]",x)
print dict(y)
Try this.Simple and done in one or two steps.
import re
val = "{t:30, f:50}"
t = re.search("[^{].*[^}]",val).group()
print (t)
z = t.split(",")
print (z)
mydict = {}
mydict[z[0][0]]=z[0][2]+z[0][3]
print (mydict)
>>>
t:30, f:50
['t:30', ' f:50']
{'t': '30'}
>>>
Use search() method ofre module

Categories

Resources