How to put pickle dict value into an object - python

I am using pickle to dump a dictionary object into a txt file. I need to grab the dictionary from the file and extract only certain values and put them inside of an object as a string.
My dictionary looks something like this:
obj_dict = { 'name': 'MYID', 'value': 'usdf23444',
'name': 'MYID2', 'value' : 'asdfh3479' }
Part of the dilemma I have is that there are two 'name' and two 'value' in the dictionary and I need to grab each separately.
Here is the code I am using:
import pickle
filepath = file.txt
output = open(filepath, 'rb')
obj_dict = pickle.load(output)
for i in obj_dict:
NewString = "VALUE1=" + i['value1'] + "VALUE2=" + i['value2']
print(NewString)
I know this code doesn't work, I'm more showing what I need my end result to look like but basically I need each value to be put into a string that I can use later. How can I reference 'value1' and 'value2' correctly? Also I am getting this error when trying to just get one 'value':
TypeError: list indices must be integers or slices, not str
EDIT FOR COMMENT 2
I'm not sure if that's true, I can run this code:
output = open(filepath, 'rb')
obj_dict = pickle.load(output)
for i in obj_dict:
print(i['value'])
and my output is:
usdf23444
asdfh3479

After the update, it looks like it is a list of dicts. Try:
strings = ["VALUE{}={}".format(i, d['value']) for i, d in enumerate(obj_dict)]

Related

I can't get a value from a JSON API response in python

So I am struggling with getting a value from a JSON response. Looking in other post I have managed to write this code but when I try to search for the key (character_id) that I want in the dictionary python says that the key doesn't exist. My solution consists in getting the JSON object from the response, converting it into a string with json.dumps() and the converting it into a dictionary with json.loads(). Then I try to get 'character_id' from the dictionary but it doesn't exist. I am guessing it is related with the format of the dictionary but I have little to none experience in python. The code that makes the query and tries to get the values is this: (dataRequest is a fuction that makes the request and return the response from the api)
characterName = sys.argv[1];
response = dataRequest('http://census.daybreakgames.com/s:888/get/ps2:v2/character/?name.first_lower=' + characterName + '&c:show=character_id')
jsonString = json.dumps(response.json())
print(jsonString)
dic = json.loads(jsonString)
print(dic)
if 'character_id' in dic:
print(dic['character_id'])
The output of the code is:
{"character_list": [{"character_id": "5428662532301799649"}], "returned": 1}
{'character_list': [{'character_id': '5428662532301799649'}], 'returned': 1}
Welcome #Prieto! From what I can see, you probably don't need to serialize/de-serialize the JSON -- response.json() returns a python dictionary object already.
The issue is that you are looking for the 'character_id' key at the top-level of the dictionary, when it seems to be embedded inside another dictionary, that is inside a list. Try something like this:
#...omitted code
for char_obj in dic["character_list"]:
if "character_id" in char_obj:
print(char_obj["character_id"])
if your dic is like {"character_list": [{"character_id": "5428662532301799649"}], "returned": 1}
you get the value of character_id by
print(dic['character_list'][0][character_id])
The problem here is that you're trying to access a dictionary where the key is actually character_list.
What you need to do is to access the character_list value and iterate over or filter the character_id you want.
Like this:
print(jsonString)
dic = json.loads(jsonString)
print(dic)
character_information = dic['character_list'][0] # we access the character list and assume it is the first value
print(character_information["character_id"]) # this is your character id
The way I see it, the only hiccup with the code is this :
if 'character_id' in dic:
print(dic['character_id'])
The problem is that, the JSON file actually consists of actually 2 dictionaries , first is the main one, which has two keys, character_list and returned. There is a second sub-dictionary inside the array, which is the value for the key character_list.
So, what your code should actually look like is something like this:
for i in dic["character_list"]:
print(i["character_id"])
On a side-note, it will help to look at JSON file in this way :
{
"character_list": [
{
"character_id": "5428662532301799649"
}
],
"returned": 1
}
,where, elements enclosed in curly-brackets'{}' imply they are in a dictionary, whereas elements enclosed in curly-brackets'[]' imply they are in a list

Sort a list dictionaries by a value of dictionary? TypeError: string indices must be integers

I wrote a Python script that allows me to retrieve in a file some information like the e-value, number of accession... I then store this information in a dictionary.
import operator
file = open("4.A.1.1.3.txt", "r")
line = file.readline()
dico_hit = dict()
for line in file :
if '#' not in line :
columns = line.split()
query = columns[3]
accession = columns[4]
evalue = columns[6]
hmmfrom = int(columns[15])
hmmto = int(columns[16])
dico_hit[query] = {'Accession' : accession, 'E-value' : evalue,'Hmmfrom' : hmmfrom, 'Hmmto' : hmmto}
Here's a preview of my dictionary:
PTS_EIIB {'Accession': 'PF00367.21', 'E-value': '4.9e-21', 'Hmmfrom': '2', 'Hmmto': '34'}
PTS_EIIC {'Accession': 'PF02378.19', 'E-value': '8.9e-92', 'Hmmfrom': '1', 'Hmmto': '324'}
I want to sort my dictionary list by one of the dictionary values (E-value). For this I use the function "sorted".
sort_evalue= sorted(dico_hit, key=lambda k: k['E-value'])
print(sort_evalue)
I get that mistake:
TypeError: string indices must be integers
I don't understand what's causing this mistake? Is this just not the right way to go about it?
dico_hit is not a list, it is a dict, if you want to sort them you should use list. so before your loop:
dico_hit = list()
then append to list like this insted of dico_hit[query] = {'Ac...:
dico_hit.append({'Accession' : accession, 'E-value' : evalue,'Hmmfrom' : hmmfrom, 'Hmmto' : hmmto})
then your sorted function will work just fine.
by the way:
you can not sort dictionary because of their base implementation. for ordering dicts you can use collections.OrderedDict.

Python 2.7 parsing data

I have data that look like this:
data = 'somekey:value4thekey&second-key:valu3-can.be?anything&third_k3y:it%can have spaces;too'
In a nice human-readable way it would look like this:
somekey : value4thekey
second-key : valu3-can.be?anything
third_k3y : it%can have spaces;too
How should I parse the data so when I do data['somekey'] I would get >>> value4thekey?
Note: The & is connecting all of the different items
How am I currently tackling with it
Currently, I use this ugly solution:
all = data.split('&')
for i in all:
if i.startswith('somekey'):
print i
This solution is very bad due to multiple obvious limitations. It would be much better if I can somehow parse it into a python tree object.
I'd split the string by & to get a list of key-value strings, and then split each such string by : to get key-value pairs. Using dict and list comprehensions actually makes this quite elegant:
result = {k:v for k, v in (part.split(':') for part in data.split('&'))}
You can parse your data directly to a dictionary - split on the item separator & then split again on the key,value separator ::
table = {
key: value for key, value in
(item.split(':') for item in data.split('&'))
}
This allows you direct access to elements, e.g. as table['somekey'].
If you don't have objects within a value, you can parse it to a dictionary
structure = {}
for ele in data.split('&'):
ele_split = ele.split(':')
structure[ele_split[0]] = ele_split[1]
You can now use structure to get the values:
print structure["somekey"]
#returns "value4thekey"
Since the keys have a common format of being in the form of "key":"value".
You can use it as a parameter to split on.
for i in x.split("&"):
print(i.split(":"))
This would generate an array of even items where every even index is the key and odd index being the value. Iterate through the array and load it into a dictionary. You should be good!
I'd format data to YAML and parse the YAML
import re
import yaml
data = 'somekey:value4thekey&second-key:valu3-can.be?anything&third_k3y:it%can have spaces;too'
yaml_data = re.sub('[:]', ': ', re.sub('[&]', '\n', data ))
y = yaml.load(yaml_data)
for k in y:
print "%s : %s" % (k,y[k])
Here's the output:
third_k3y : it%can have spaces;too
somekey : value4thekey
second-key : valu3-can.be?anything

Add a key that contains a list in json

I need to add a key to a json. I have the following json on a variable:
[{"id":00000,"alert":"testing"}]
But I need the json object look like this:
{'keyA':[{"id":00000,"alert":"testing"}]}
How can I concatenate this key to the list?
Thx!
Just add the first object to a new dictionary like this:
jsonobj = [{"id":00000,"alert":"testing"}]
result = {'keyA':jsonobj}
and then you can either work with this dictionary or get the json value of it like:
import json
json.dumps(result)
And if you get only the json version of the input you have to use something like:
jsonobj = json.loads('[{"alert": "testing", "id": 0}]')
result = {'keyA':jsonobj}
json.dumps(result)

Dictionaries under dictionary are copied by value not copied by reference?

In the beginning I create xls_dict and xml_dict
Then wrapped the above 2 dicts into dictionary's creation. (I though it is copy be reference)
So I will load the json files into the 2 dicts.
However, I found when I exit the
for export_file, data_dict in json_files.iteritems(): block.
the xls_dict and xml_dict are not changed.
The was not my expectation.
Where did I misunderstand ? Thanks
xls = MultiLangXls(xls_path, XLS_COLUMN)
xls_dict = xls.load()
xml = MultiLangXML(xml_path)
xml_dict = xml.load()
json_files={
"xls.json": xls_dict,
"xml.json": xml_dict
}
for export_file, data_dict in json_files.iteritems():
if os.path.isfile(export_file):
pass
else: # If json file not exists, then ouput the dict into json file
with open( export_file , 'w') as f:
json.dump(data_dict, f, encoding="utf-8")
load_file = open(export_file).read().decode("utf-8-sig")
data_dict = {}
data_dict = json.loads( load_file )
The data_dict variable does refer to the same object and not to a copy. Assigning a new dict to data_dict, however, disconnects the variable from that object and assigns to it a brand new one.
To clear the existing dict, and fill it with new contents, you want to write something like this:
data_dict.clear()
data_dict.update(json.loads(load_file))
Problem here:
data_dict = {} #You create new empty dictionary
# And rewrite it. But old dictionare are not cleaned.
data_dict = json.loads( load_file )
You must clean by data_dict.clean()
You are reassigning data_dict to a new dictionary object.
See Passing values in Python

Categories