You have to iterate over the list of dictionaries and search for the one with the given id_number. Once you find it you can print the rest of its data and break, assuming id_number is unique.
data = [
{
"id_number": "SA4784",
"name": "Mark",
"birthdate": None
},
{
"id_number": "V410Z8",
"name": "Vincent",
"birthdate": "15/02/1989"
},
{
"id_number": "CZ1094",
"name": "Paul",
"birthdate": "27/09/1994"
}
]
for i in data:
if i['id_number'] == 'V410Z8':
print(i['birthdate'])
print(i['name'])
break
If you have control over the data structure, a more efficient way would be to use the id_number as a key (again, assuming id_number is unique):
data = { "SA4784" : {"name": "Mark", "birthdate": None},
"V410Z8" : { "name": "Vincent", "birthdate": "15/02/1989"},
"CZ1094" : {"name": "Paul", "birthdate": "27/09/1994"}
}
Then all you need to do is try to access it directly:
try:
print(data["V410Z8"]["name"])
except KeyError:
print("ID doesn't exist")
>> "Vincent"
Answer from DeepSpace on Stack OverflowYou have to iterate over the list of dictionaries and search for the one with the given id_number. Once you find it you can print the rest of its data and break, assuming id_number is unique.
data = [
{
"id_number": "SA4784",
"name": "Mark",
"birthdate": None
},
{
"id_number": "V410Z8",
"name": "Vincent",
"birthdate": "15/02/1989"
},
{
"id_number": "CZ1094",
"name": "Paul",
"birthdate": "27/09/1994"
}
]
for i in data:
if i['id_number'] == 'V410Z8':
print(i['birthdate'])
print(i['name'])
break
If you have control over the data structure, a more efficient way would be to use the id_number as a key (again, assuming id_number is unique):
data = { "SA4784" : {"name": "Mark", "birthdate": None},
"V410Z8" : { "name": "Vincent", "birthdate": "15/02/1989"},
"CZ1094" : {"name": "Paul", "birthdate": "27/09/1994"}
}
Then all you need to do is try to access it directly:
try:
print(data["V410Z8"]["name"])
except KeyError:
print("ID doesn't exist")
>> "Vincent"
Using lambda in Python
data = [
{
"id_number": "SA4784",
"name": "Mark",
"birthdate": None
},
{
"id_number": "V410Z8",
"name": "Vincent",
"birthdate": "15/02/1989"
},
{
"id_number": "CZ1094",
"name": "Paul",
"birthdate": "27/09/1994"
}
]
Using Lambda and filter
print(list(filter(lambda x:x["id_number"]=="CZ1094",data)))
Output
[{'id_number': 'CZ1094', 'name': 'Paul', 'birthdate': '27/09/1994'}]
I have a very big json file that I have loaded into my script. Each item has many keys each with a unique value.
I am interested in only one key, 'filename' so I need to ignore all other keys. A user will input a query in an input prompt and if the value exists as a filename then it returns another value associated with a different key.
To illustrate here is an example of the json:
[
{
'filename': 'file1',
'size': '56B'
'id': '1'
},
{
'filename': 'file2',
'size': '100B'
'id': '2'
},
{
'filename': 'file3',
'size': '1KB'
'id': '3'
}
]
and the user inputs the query 'file3'
How would I get the script to search only the filename keys for the matching string 'file3' and when it finds it, it needs to return the value '3' corresponding to the id key in the same entry?
import json
data=json.load(open("file.json"))
for key in data:
A1 = int("0xffff123123", 16)
obj = data.get(key)
x1 = obj.get('X1')
x1 = int(x1, 16)
if A1%x1 > 2:
# print what you need
print("Module greater than 2")
else:
print("No match")
I don't know if it's exactly what you need, but in this way in x1 you have the value of the field X1 for each JSON object. Is up to you add the correct logic to the program (if statement).
Pay attention: you paste a JSON in which you have characters different from doublequotes (").
I would shape your code like this:
import json
A1 = int("0xffff123123", 16)
with open('test1.json') as f:
data = json.load(f)
for key in data:
value = data.get(key)
X1 = int(value.get("X1"), 16)
if A1%X1 > 2:
print("The modulo is greater then 2")
else:
print("No match")
Notice that the steps are: open the file, load the JSON, loop the objects doing your task.
Is also important you check your JSON string since some of the double quotes in there are not really double quotes and this surely will impact your run
I'm doing a fair amount of work with APIs. Usually I need to take the response and then output to a CSV then search through it for specific data and possibly manipulate it. Trying to search the JSON itself for a specific key value has proven more difficult than I expected. Is there an easier way to do this? Am I just making this harder than it needs to be?
Here is a one-liner example for searching:
aaa = {
"success":True,
"data":
{
"array":
[
{
"id":"1","name":"Value1"
},
{
"id":"2","name":"Value2"
}
]
}
}
[a['name'] for a in aaa['data']['array'] if a['id']=='1']
This will return all the found cases, or an empty array if nothing is found
Not sure where that piece of code came from but it looks very wrong.
Just looking at the structure you can do something like:
for attrs in r.json()['data']['array']:
if attrs['name'] == s_name:
ident = attrs['id']
name = attrs['name']
print(name, '-', ident)
break
else:
print('Nothing found!')
ObjectPath is a library that provides ability to query JSON and nested structures of dicts and lists. For example, you can search for all attributes called "foo" regardless how deep they are by using $..foo.
While the documentation focuses on the command line interface, you can perform the queries programmatically by using the package's Python internals. The example below assumes you've already loaded the data into Python data structures (dicts & lists). If you're starting with a JSON file or string you just need to use load or loads from the json module first.
import objectpath
data = [
{'foo': 1, 'bar': 'a'},
{'foo': 2, 'bar': 'b'},
{'NoFooHere': 2, 'bar': 'c'},
{'foo': 3, 'bar': 'd'},
]
tree_obj = objectpath.Tree(data)
tuple(tree_obj.execute('$..foo'))
# returns: (1, 2, 3)
Notice that it just skipped elements that lacked a "foo" attribute, such as the third item in the list. You can also do much more complex queries, which makes ObjectPath handy for deeply nested structures (e.g. finding where x has y that has z: $.x.y.z). I refer you to the documentation and tutorial for more information.
As json.loads simply returns a dict, you can use the operators that apply to dicts:
>>> jdata = json.load('{"uri": "http:", "foo", "bar"}')
>>> 'uri' in jdata # Check if 'uri' is in jdata's keys
True
>>> jdata['uri'] # Will return the value belonging to the key 'uri'
u'http:'
Edit: to give an idea regarding how to loop through the data, consider the following example:
>>> import json
>>> jdata = json.loads(open ('bookmarks.json').read())
>>> for c in jdata['children'][0]['children']:
... print 'Title: {}, URI: {}'.format(c.get('title', 'No title'),
c.get('uri', 'No uri'))
...
Title: Recently Bookmarked, URI: place:folder=BOOKMARKS_MENU(...)
Title: Recent Tags, URI: place:sort=14&type=6&maxResults=10&queryType=1
Title: , URI: No uri
Title: Mozilla Firefox, URI: No uri
Inspecting the jdata data structure will allow you to navigate it as you wish. The pprint call you already have is a good starting point for this.
Edit2: Another attempt. This gets the file you mentioned in a list of dictionaries. With this, I think you should be able to adapt it to your needs.
>>> def build_structure(data, d=[]):
... if 'children' in data:
... for c in data['children']:
... d.append({'title': c.get('title', 'No title'),
... 'uri': c.get('uri', None)})
... build_structure(c, d)
... return d
...
>>> pprint.pprint(build_structure(jdata))
[{'title': u'Bookmarks Menu', 'uri': None},
{'title': u'Recently Bookmarked',
'uri': u'place:folder=BOOKMARKS_MENU&folder=UNFILED_BOOKMARKS&(...)'},
{'title': u'Recent Tags',
'uri': u'place:sort=14&type=6&maxResults=10&queryType=1'},
{'title': u'', 'uri': None},
{'title': u'Mozilla Firefox', 'uri': None},
{'title': u'Help and Tutorials',
'uri': u'http://www.mozilla.com/en-US/firefox/help/'},
(...)
}]
To then "search through it for u'uri': u'http:'", do something like this:
for c in build_structure(jdata):
if c['uri'].startswith('http:'):
print 'Started with http'
After your edit I can say that there is no faster/more efficient way than turning your JSON into python 2-dimensional list and loop through each node and compare second field with your "keyvalue".
EDIT: faster/more efficient
your_dict = {'a': 1, 'b': 2, 'c': 'asd'} # the dictionary
your_value = 'asd' # the value to look for
[elem for elem in your_dict.iteritems() if elem[1] == 'asd'] # look for entry with value == your_value
Output: [('c', 'asd')]
EDIT:
for a list:
your_list = [['a', 1], ['b', 2], ['c', 'asd']] # the list
your_value = 'asd' # the value to look for
[elem for elem in your_list if elem[1] == 'asd'] # look for element with value == your_value
Output: [('c', 'asd')]
As I said in my other answer, I don't think there is a way of finding all values associated with the "P1" key without iterating over the whole structure. However I've come up with even better way to do that which came to me while looking at @Mike Brennan's answer to another JSON-related question How to get string objects instead of Unicode from JSON?
The basic idea is to use the object_hook parameter that json.loads() accepts just to watch what is being decoded and check for the sought-after value.
Note: This will only work if the representation is of a JSON object (i.e. something enclosed in curly braces {}), as in your sample.
from __future__ import print_function
import json
def find_values(id, json_repr):
results = []
def _decode_dict(a_dict):
try:
results.append(a_dict[id])
except KeyError:
pass
return a_dict
json.loads(json_repr, object_hook=_decode_dict) # Return value ignored.
return results
json_repr = '{"P1": "ss", "Id": 1234, "P2": {"P1": "cccc"}, "P3": [{"P1": "aaa"}]}'
print(find_values('P1', json_repr))
(Python 3) output:
['cccc', 'aaa', 'ss']
I had the same issue just the other day. I wound up just searching through the entire object and accounted for both lists and dicts. The following snippets allows you to search for the first occurrence of a multiple keys.
import json
def deep_search(needles, haystack):
found = {}
if type(needles) != type([]):
needles = [needles]
if type(haystack) == type(dict()):
for needle in needles:
if needle in haystack.keys():
found[needle] = haystack[needle]
elif len(haystack.keys()) > 0:
for key in haystack.keys():
result = deep_search(needle, haystack[key])
if result:
for k, v in result.items():
found[k] = v
elif type(haystack) == type([]):
for node in haystack:
result = deep_search(needles, node)
if result:
for k, v in result.items():
found[k] = v
return found
deep_search(["P1", "P3"], json.loads(json_string))
It returns a dict with the keys being the keys searched for. Haystack is expected to be a Python object already, so you have to do json.loads before passing it to deep_search.
Any comments for optimization are welcomed!
Here’s an easy way to do it:
def function(json_object, name):
for dict in json_object:
if dict['name'] == name:
return dict['price']
If you are sure that there are no duplicate names, an even more effective (and pythonic) way to do it is to use list comprehensions:
def function(json_object, name):
return [obj for obj in json_object if obj['name']==name][0]['price']
from json import loads
json = """[
{
"name":"Apple",
"price":2,
"have":0,
"max":36
},
{
"name":"Pineapple",
"price":5,
"have":6,
"max":17
}
]"""
parsedJson = loads (json)
def jsonname (name):
for entry in parsedJson:
if name == entry ['name']:
return entry ['price']