Having trouble parsing some JSON in python - python

I'm trying to parse some JSON data from https://mtgjson.com/json/AllCards.json but I'm not sure how to deal with the way its structured. Here's a snippet of my code:
cards = json.loads(open("AllCards.json", encoding="utf8").read())
for card in cards:
print(card)
I was expecting "card" to be a dictionary that I could then use to access attributes, for example "card['name']". However all "card" is in this case is a string containing the the key value so I cant use it to access any of the nested attributes. If I print "cards" though, it outputs the entire JSON document including all of the nested attributes.
I also tried accessing them using cards[0] but this gave me a key error.
I'm obviously missing something here but I cant figure out what.

Iterating a dictionary will by default iterate its keys.
If you walso want the values, you should iterate dict.items() instead:
import json
cards = json.loads(open("AllCards.json", encoding="utf8").read())
for key, value in cards.items():
print(key, value)
value will contain the sub-dict.
It's the same as
import json
cards = json.loads(open("AllCards.json", encoding="utf8").read())
for key in cards:
print(key, cards[key])
If you don't care about the key, you can iterate the values directly:
import json
cards = json.loads(open("AllCards.json", encoding="utf8").read())
for card in cards.values():
print(card)

Related

How to Identify an dictionary inside an dictionary

I have a dictionary like this:
test = {'user_id':125, 'company':'XXXX', 'payload': {"tranx": "456b62448367","payload": {"snr": "25%","Soil": 45,"humidity": 85}}}
The requirement is :
the payload inside a dictionary(test), is dynamic sometimes the payload will come and sometimes it won't, and the payload name is temporary, may after some time it will become "abc" or anything.
In this case,
I want to Identify the "test" is a nested dict or not.
If it is nested dict I want to know the "key" of the nested dictionary, How can I solve this.
iterate and check
for key, value in outer_dict.items():
if isinstance(value, dict):
print(key)

Handling a dictionary that has keys that are unicode strings

I have a dictionary that each key is unicode and I'm using the following code to insert JSON file into a dictionary.
def readDictFromFile(filename):
my_file = Path(filename)
if my_file.is_file():
return json.load(codecs.open(filename,encoding='utf-8'))
return {}
But when I try to check if a string is in the dictionary, it does not work:
if title in dict:
continue
The reason is that the dict contains keys that look like: u'\u05d5. I say that I need to use repr (link) but is there a way to do it with the same syntax without looping for each key in the dict?

Unable to store non-characters text in a dictionary in python

I am trying sentiment analysis where I have data like
source_text-> #LiesbethHBC I have a good feeling actually 🙈 its not that long, it's pretty soon!\nAw you deserve these tickets
then! 💖
result_value-> Sentiment(polarity=0.0, subjectivity=0.0)
I want to store this key value pair in a python dictionary.
I tried creating one as:
dict={}
dict[source_text].append(result_value)
but I get KeyError
Is there a way to store such text(just not characters) in a dictionary?
Your problem has nothing to do with "non-character text" (which doesn't mean anything actually), the only requirement for an object to be usable as a dict key is that it's hashable, and there's absolutely no restriction on what you can use as value.
Your problem quite simply comes from the fact that you're trying to get the value for an inexistant key (that's what KeyError means : the key you ask for does not exist in the dict).
Here :
mydict = {}
at this point, mydict is empty so just any item access will raise a KeyError
then you're doing this:
dict[source_text].append(result_value)
which is basically:
something = mydict[source_text] # get value for key `source_text`
something.append(result_value)
Since your dict is empty, the first line WILL obviously raise a KeyError.
If you want to store one unique result_value for each source_text value then the proper syntax is:
mydict[source_text] = result_value
If you want to store a list of result_value for each source_text value then you have to either explicitely test if the key is set, if not set it with an empty list, then append to this list:
if source_text not in mydict:
mydict[source_text] = []
mydict[source_text].append(result_value)
or just use a DefaultDict instead:
from collections import DefaultDict
mydict = DefaultDict(list)
# DefaultDict will automagically create the key with an empty list
# as value if the key is missing
mydict[source_text].append(result_value)
Now I strongly suggest that you invest some time in properly learning Python (hint: there's a quite decent tutorial in the official documentation) if you have to use it, this will save on everyone's time.
The problem is that when you tried to pull out the key #LiesbethHBC I have a good feeling actually 🙈 its not that long, it's pretty soon!\nAw you deserve these tickets then! 💖 in the dictionary which in this case is non-existent, Python gave you a KeyError meaning that the key didn't exist in the dictionary. A simple way to solve this is by initially checking whether you have that particular key in the dictionary, if yes, do whatever you wanna do with it, else create that key first.
By the way, avoid using dict (dictionary datatype) or any other datatypes as a variable name.
This is what you should actually do:
dictionary = {} # Since, 'dict' is the dictionary data-type in Python
if (source_text in dictionary):
# If the key exists...
dictionary[source_text].append(result_value)
else:
# If the key does not exist...
dictionary[source_text] = []
This should help...
Have you tried using '.update' method?
dict = {}
dict.update({'First':'Test'})
dict.update({'Lets Get':'Real'})
print (dict)
Output:
{'Testing': 'Dictionaries', 'Lets Get': 'Real'}
EDIT:
Or even:
dict = {}
dict.update({'Polarity':0.91})
dict.update({'Subjectivity':0.73})
print (dict)
Output:
{'Polarity': 0.8, 'Subjectivity': 0.73}

Using A Python List or String in Dictionary Lookup?

Use Case
I am making a factory type script in Python that consumes XML and based on that XML, returns information from a specific factory. I have created a file that I call FactoryMap.json that stores the mapping between the location an item can be found in XML and the appropriate factory.
Issue
The JSON in my mapping file looks like:
{
"path": "['project']['builders']['hudson.tasks.Shell']",
"class": "bin.classes.factories.step.ShellStep"
}
path is where the element can be found in the xml once its converted to a dict.
class is the corresponding path to the factory that can consume that elements information.
In order to do anything with this, I need to descend into the dictionaries structure, which would look like this if I didn't have to draw this information from a file(note the key reference = 'path' from my json'):
configDict={my xml config dict}
for k,v in configDict['project']['builders']['hudson.tasks.Shell'].iteritems():
#call the appropriate factory
The issue is that if I look up the path value as a string or a list, I can not use it in 'iteritems'():
path="['project']['builders']['hudson.tasks.Shell']" #this is taken from the JSON
for k,v in configDict[path].iteritems():
#call the appropriate factory
This returns a key error stating that I can't use a string as the key value. How can I used a variable as the key for that python dictionary?
You could use eval:
eval( "configDict"+path )
You can use the eval() function to evaluate your path into an actual dict object vs a string. Something like this is what I'm referring to:
path="['project']['builders']['hudson.tasks.Shell']" #this is taken from the JSON
d = eval("configDict%s" % path)
for k,v in d.iteritems():
#call the appropriate factory

Printing output from json

I am still new to python, and brand new to json. I am trying to go through output that is in json. I am not yet sure which fields will need to be printed out, but I do know that two of them will be needed.
How could I change:
import json
from pprint import pprint
with open('out.json') as data_file:
data = json.load(data_file)
pprint(data)
to print out say, field one, and field two?
I figure if I can print field one, and two, I can play around with it until I find the right fields. I imagine this is a derp level question, but being able to print specific fields is what I need to be able to do.
json.load is returning python obj (https://docs.python.org/3/library/json.html#json.load) so depending on content of 'out.json' it can be either dict, list or few other types.
In case of dictionary you can go with data['key'] or if it's list go with data[index] - where index is 1,2,...
For looping use for ie for list:
for elem in data:
print(elem)
of for dictionary:
for key, value in data.items():
print(key, value)
You could have find it easily in python's json documentation.
Here data is a dict type object. You can get any value by using the corresponding key like this:
print data['field']
But it will throw a KeyError if the field key is not present in the dict. For avoiding this issue you can use the get() method.
print data.get('field')
This will return None in case of missing key.

Categories

Resources