Get a FIRST value of json dictionary in python - python

I have json like this, in python.
{
"unknown1": {
"somekeys": "somevalues"
}
"unknown2": {
"somekeys": "somevalues"
}
"unknown3": {
"somekeys": "somevalues"
}
}
Is there a way to get ONLY unknown1 dictionary?
Unknowns are really unknowns and are different each time.
The speed of this operation is critical.
(I know how to load the json with json.loads)

No, there is no way to do this
In the comments, you write:
But isn't there a way to, maybe, iterate throu this json so it give me unknown1 dictionary on the first iteration or something like this? Or it would be as random as iterateing thru python dictionary?
That's exactly correct. When you load json into python using json.load() or json.loads, the json string is converted into a python dict. So, once it's loaded, you should treat it like any other dict, because it is one.

try to use some loop system
like this
first_value
for i in JsonFile:
first_value = i
break
first_value is the first dictionary

Related

What would be the most optimised way to access values in a nested array whilst respecting pep8?

I have been using nested arrays parsed from a json.
This ends up giving a gigantic line each time I try to access values in the data.
let's say I have a nested array in the var data, when I try to reach the deeper values, I still have to respect the 80 characters limit. All I want to do is read or modify the value.
self.data["name1"]["name2"][varWithNumber][varWithNumber2][varWithNumber3]
Now, I thought about two possible solutions I could use:
1- split it using temporary vars and then reasign it to the data once I am done ex:
tempData=self.data["name1"]["name2"][varWithNumber]
tempData[varWithNumber2][varWithNumber3]+=1
self.data["name1"]["name2"][varWithNumber]=tempData
I guess this solution would use quite a bit of ressources from all the memory copied around.
2- use the exec function implemented in python and split the string on multiple lines:
exec ('self.data'+
'["name1"]'+
'["name2"]'+
'[varWithNumber]'+
'[varWithNumber2]'+
'[varWithNumber3]+=1')
I have no idea how optimised is the exec function. What would be the most pythonic/optimised way to do this? Is there any other/better way to reach the goal whilst respecting the pep8?
(Bit long for a comment) You don't need exec to do that... you can use the line continuation operator:
self.data["name1"]\
["name2"]\
[varWithNumber]\
[varWithNumber2]\
[varWithNumber3]
Demo:
In [635]: x = [[[[1, 2, 3]]]]
In [636]: x[0]\
...: [0]\
...: [0]\
...: [0]
Out[636]: 1
This seems like the easiest and cleanest way to do it.
Don't use exec unless you have to. Actually, don't use it, ever.
In some cases, keeping a reference to a sub dict works if you are to frequently visit that part of your data structure again and again. It is a matter of deciding what is the best solution to apply given the situation and circumstances.
You are on the right track with your first option, and it's not as memory intensive as you might think. Most things in python are references to places in memory, so let's say we have this json blob (dict in python):
test = {
"name1": {
"name2": {
"foo": {
"count": 1,
"color": "red"
}
}
}
}
Now if you wanted to change both parts of that nested "foo" key, you could first make a reference to it with:
foo_ref = test['name1']['name2']['foo']
Then it's very simple to just
foo_ref['count'] += 1
foo_ref['color'] = 'green'

How to check whether a json object is array

Im new to python.I came up with this issue while sending json arraylist obect from java to python.While sending the json object from java the json structure of the arraylist is
[{'firstObject' : 'firstVal'}]
but when i receive it in python i get the value as
{'listName':{'firstObject':'firstVal'}}
when i pass more than one object in the array like this :
[{'firstObject' : 'firstVal'},{'secondObject' : 'secondVal'}]
I am receiving the json from python end as
{'listName':[{'firstObject':'firstVal'},{'secondObject' : 'secondVal'}]}
I couldnt figure out why this is happening.Can anyone help me either a way to make the first case a array object or a way to figure out whether a json variable is array type.
Whenever you use the load (or loads) function from the json module, you get either a dict or a list object. To make sure you get a list instead of a dict containing listName, you could do the following:
import json
jsonfile = open(...) # <- your json file
json_obj = json.load(jsonfile)
if isinstance(json_obj, dict) and 'listName' in json_obj:
json_obj = json_obj['listName']
That should give you the desired result.
json module in Python does not change the structure:
assert type(json.loads('[{"firstObject": "firstVal"}]')) == list
If you see {'listName':{'firstObject':'firstVal'}} then something (either in java or in python (in your application code)) changes the output/input.
Note: it is easy to unpack 'listName' value as shown in #Fawers' answer but you should not do that. Fix the upstream code that produces wrong values instead.

Print all values from dictionary object returned with .json()

I have a piece of code that allows me to print dictionary items returned using .json() method on an XHR response from a website:
teamStatDicts = responser[u'teamTableStats']
for statDict in teamStatDicts:
print("{seasonId},{tournamentRegionId},{minsPlayed},"
.decode('cp1252').format(**statDict))
This prints in the following format:
9155,5,900
9155,5,820
...
...
...
9155,5,900
9155,5,820
The above method works fine, providing the keys in the dictionary never change. However in some of the XHR submissions I am making they do. Is there a way that I can print all dictionary values in exactly the same format as above? I've tried a few things but really didn't get anywhere.
In general, give a dict, you can do:
print(','.join(str(v) for v in dct.values()))
The problem here is you don't know the order of the values. i.e. is the first value in the CSV data the seasonId? Is the the tournamentRegionId? the minsPlayed? Or is it something else entirely that you don't know about?
So, my point is that unless you know the field names, you can't put them in a string in any reliable order if the data comes to you as vanilla dicts.
If you're decoding the XHR elsewhere using json, you could make the object_pairs_hook an OrderedDict:
from collections import OrderedDict
import json
...
data = json.loads(datastring, object_pairs_hook=OrderedDict)
Now the data is guaranteed to be in the same order as the datastring was, but that only helps if the data in datastring was ordered in a particular way (which is usually not the case).

Python how to use a string to fill a dictionary in one go?

I have this for example
Dict = {'Hello':'World', 'Hi':'Again'}
x = (str(Dict))
Dict2 = {x}
print (Dict2)
I understand why it doesn't work that way but i'm new to python and have no idea what i'm doing.
I'd like to be able to export my dictionary to a variable (here x) and then able to fill another dictionary with it. I don't want to use the dict.copy() command, beacause the variable x will be stored on a txt file.
Any help is highly appreciated.
Thanks in advance.
If you actually want to use a string to do the copying, you can say:
Dict2 = eval(repr(Dict))
but there's no reason you would ever need to do that. Use dict.copy() instead.
EDIT: Based on what you said in the comments, json, as another user has already pointed out, is the best way to go. That would look like this:
import json
with open("file.txt", "w") as f:
json.dump(Dict, f)
with open("file.txt") as f:
Dict2 = json.load(f)
If what you're looking for is to save a dict-like string representation to a file so you can load it later, use the json module. (This is not at all the same as "exporting a dictionary to a variable", but your comment indicates that what you're really trying to do is save a dictionary to a file.)
What you can do to specifically address what you asked is:
Dict = {'Hello':'World', 'Hi':'Again'}
x = str(Dict)
Dict2 = dict((y.split(':') for y in x[1:-1].strip().replace(" ","").replace("'","").split(',')))
or if you want to use dictionary comprehension
Dict2 = {y.split(':')[0]:y.split(':')[1] for y in x[1:-1].strip().replace(" ","").replace("'","").split(',')}
But I really would not suggest doing it this way. Instead I was suggest looking at either pickle or json to save the dictionary to file.

Best way to encode tuples with json

In python I have a dictionary that maps tuples to a list of tuples. e.g.
{(1,2): [(2,3),(1,7)]}
I want to be able to encode this data use it with javascript, so I looked into json but it appears keys must be strings so my tuple does not work as a key.
Is the best way to handle this is encode it as "1,2" and then parse it into something I want on the javascript? Or is there a more clever way to handle this.
You might consider saying
{"[1,2]": [(2,3),(1,7)]}
and then when you need to get the value out, you can just parse the keys themselves as JSON objects, which all modern browsers can do with the built-in JSON.parse method (I'm using jQuery.each to iterate here but you could use anything):
var myjson = JSON.parse('{"[1,2]": [[2,3],[1,7]]}');
$.each(myjson, function(keystr,val){
var key = JSON.parse(keystr);
// do something with key and val
});
On the other hand, you might want to just structure your object differently, e.g.
{1: {2: [(2,3),(1,7)]}}
so that instead of saying
myjson[1,2] // doesn't work
which is invalid Javascript syntax, you could say
myjson[1][2] // returns [[2,3],[1,7]]
If your key tuples are truly integer pairs, then the easiest and probably most straightforward approach would be as you suggest.... encode them to a string. You can do this in a one-liner:
>>> simplejson.dumps(dict([("%d,%d" % k, v) for k, v in d.items()]))
'{"1,2": [[2, 3], [1, 7]]}'
This would get you a javascript data structure whose keys you could then split to get the points back again:
'1,2'.split(',')
My recommendation would be:
{ "1": [
{ "2": [[2,3],[1,7]] }
]
}
It's still parsing, but depending on how you use it, it may be easier in this form.
You can't use an array as a key in JSON. The best you can do is encode it. Sorry, but there's really no other sane way to do it.
Could it simply be a two dimensional array? Then you may use integers as keys

Categories

Resources