I'm trying to get Facebook's insights data. the code below was running before but its starts breaking now.
Code:
async_job = {
"id": "169817458353501",
"report_run_id": "169817458353501",
}
results = []
for item in async_job:
print(item, type(item), async_job)
data = dict(item)
results.append(data)
Error:
data = dict(item)
ValueError: dictionary update sequence element #0 has length 1; 2 is required
I have tried with the JSON module as well but seems still not working.
import json
async_job = {
"id": "169817458353501",
"report_run_id": "169817458353501",
}
results = []
for item in async_job:
print(item, type(item), async_job)
data = json.loads(item)
results.append(data)
any leads will be helpful.
You are iterating over the dict keys,
which are only one value on each itearation.
dict needs at least one key-value pair.
Maybe you wish to iterate over dict items (i.e key-value pairs):
async_job = {
"id": "169817458353501",
"report_run_id": "169817458353501",
}
results = []
for key, value in async_job.items():
data = {key: value}
results.append(data)
Alternativly you can use comprehension:
results = [{key: value} for key, value in async_job.items()]
Related
I have created a var that is equal to t.json. The JSON file is a follows:
{
"groups": {
"customerduy": {
"nonprod": {
"name": "customerduynonprod",
"id": "529646781943",
"owner": "cloudops#coerce.com",
"manager_email": ""
},
"prod": {
"name": "phishing_duyaccountprod",
"id": "241683454720",
"owner": "cloudops#coerce.com",
"manager_email": ""
}
},
"customerduyprod": {
"nonprod": {
"name": "phishing_duyaccountnonprod",
"id": "638968214142",
"owner": "cloudops#coerce.com",
"manager_email": ""
}
},
"ciasuppliergenius": {
"prod": {
"name": "ciasuppliergeniusprod",
"id": "220753788760",
"owner": "cia_developers#coerce.com",
"manager_email": "jarks#coerce.com"
}
}
}
}
my goal was to pars this JSON file and get value for "owner" and output it to a new var. Example below:
t.json = group_map
group_id_aws = group(
group.upper(),
"accounts",
template,
owner = group_map['groups']['prod'],
manager_description = "Groups for teams to access their product accounts.",
The error I keep getting is: KeyError: 'prod'
Owner occurs 4 times, so here is how to get all of them.
import json
# read the json
with open("C:\\test\\test.json") as f:
data = json.load(f)
# get all 4 occurances
owner_1 = data['groups']['customerduy']['nonprod']['owner']
owner_2 = data['groups']['customerduy']['prod']['owner']
owner_3 = data['groups']['customerduyprod']['nonprod']['owner']
owner_4 = data['groups']['ciasuppliergenius']['prod']['owner']
# print results
print(owner_1)
print(owner_2)
print(owner_3)
print(owner_4)
the result:
cloudops#coerce.com
cloudops#coerce.com
cloudops#coerce.com
cia_developers#coerce.com
You get a key error since the key 'prod' is not in 'groups'
What you have is
group_map['groups']['customerduy']['prod']
group_map['groups']['ciasuppliergenius']['prod']
So you will have to extract the 'owner' from each element in the tree:
def s(d,t):
for k,v in d.items():
if t == k:
yield v
try:
for i in s(v,t):
yield i
except:
pass
print(','.join(s(j,'owner')))
If your JSON is loaded in variable data, you can use a recursive function
that deals with the two containers types (dict and list) that can occur
in a JSON file, recursively:
def find_all_values_for_key(d, key, result):
if isinstance(d, dict):
if key in d:
result.append(d[key])
return
for k, v in d.items():
find_all_values_for_key(v, key, result)
elif isinstance(d, list):
for elem in d:
find_all_values_for_key(elem, key, result)
owners = []
find_all_values_for_key(data, 'owner', owners)
print(f'{owners=}')
which gives:
owners=['cloudops#coerce.com', 'cloudops#coerce.com', 'cloudops#coerce.com', 'cia_developers#coerce.com']
This way you don't have to bother with the names of intermediate keys, or in general the structure of your JSON file.
You don't have any lists in your example, but it is trivial to recurse through
them to any dict with an owner key that might "lurk" somewhere nested
under a a list element, so it is better to deal with potential future changes
to the JSON.
I have a dictionary of dictionaries, like given below:
{
"dev": {
"project_id": "dev_project_id",
"secret_id": "dev_secret_id",
"secret_project_id": "dev_secret_project_id",
"service_account_email": "dev_service_account_email#gmail.com",
"email_list": ["dev_email#gmail.com"],
"core_func_path":"dev/core_func.py",
"secret_id_email": "dev_secret_id_email"
},
"prod": {
"project_id": "prod_project_id",
"secret_id": "prod_secret_id",
"secret_project_id": "prod_secret_project_id",
"service_account_email": "prod_service_account_email#gmail.com",
"email_list": ["prod_email_list#gmail.com"],
"core_func_path":"prod/core_func.py",
"secret_id_email": "prod_secret_id_email"
}
}
And I need to extract key when a specific project_id is provided.
Till now, I have this code, which can get values from a dictionary, however, it is failing for a dictionary of dictionaries.
check_project_id='dev_project_id'
curr_dir = Path(os.path.dirname(os.path.abspath(__file__)))
default_config_dir = os.fspath(Path(curr_dir.parent.parent, 'config').resolve())
constants_path = str(default_config_dir)+'/config.json'
with open(constants_path, 'r') as f:
std_config = json.load(f)
for val in std_config.values():
if(val['project_id']==check_project_id):
print(list(std_config.keys())[list(std_config.values()).index(check_project_id)])
Is there any way I can implement this?
So if I understand correctly, std_config is your dictionary of dictionaries. Just use the items call on the dictionary to be able to extract the key that matches your criteria.
for k, v in std_config.items():
if v["project_id"] == check_project_id:
print(k)
> dev
I am trying to get all keys from a json file in Python.
How to get nested second level(x,y) and third level keys(a,b).
For example, Keys: results,x,y,a,b
Code:
#open data
import json
with open('list.json') as f:
my_dict = json.load(f)
#1
#find keys
for key in my_dict.keys():
print("Keys : {}".format(key))
Json:
{
"results":[
{
"x":5
},
{
"x":5,
"y":[
1,
2,
3
]
},
{
"x":5,
"y":{
"a":2,
"b":67
}
}
]
}
Output:
Keys : results
You need to get the keys which are a part of the value of the JSON.
You therefore need to iterate over the values of my_dict not the keys.
Use recursive function to return all nested keys. Here is the reference stackoverflow page.
import json
def recursive_items(dictionary):
for key, value in dictionary.items():
if type(value) is list:
for i in value:
if type(i) is dict:
yield from recursive_items(i)
else:
yield key
with open('list.json') as f:
my_dict = json.load(f)
#find keys
for key in recursive_items(my_dict):
print("Keys : {}".format(key))
I have a large nested dictionary with an unknown depth and i would like to know how i can find the keys which led to the value. For example...
{'furniture':{'chair':{'sofa':{'cushion':{}}}}}
Ideally what i am looking for is a function to determine the path to the value that i have entered. I have tried researching online and this is what i tried...
def route(d,key):
if key in d: return d[key]
for k,v in d.items():
if isinstance(v,dict):
item = route(v, key)
if item is not None:
return item
This returns the items inside the key. I am looking to be able to extract the path which leads to that item. For example, route(dictionary,'sofa') then i would be able to get an expected output as such or something similar...
{'sofa':{'chair':'furniture'}}
What are some of the ways that i can achieve this ? Thanks for your help
You can do this recursively and return a list of keys that lead you to your target key:
def route(d, key):
if key in d: return [key]
for k, v in d.items():
if type(v) == dict:
found = route(v, key)
if found: return [k] + found
return []
If we run this on the following dictionary:
data = {
'furniture': {
'chair': {
'sofa': {
'cushion': {}
}
}
},
'electronics': {
'tv': {
'samsung43': 800,
'tcl54': 200
}
}
}
print(route(data, 'cushion'))
print(route(data, 'tcl54'))
print(route(data, 'hello'))
we get the following output:
['furniture', 'chair', 'sofa', 'cushion']
['electronics', 'tv', 'tcl54']
[]
Giving data organized in JSON format (code example bellow) how can we get the path of keys and sub-keys associated with a given value?
i.e.
Giving an input "23314" we need to return a list with:
Fanerozoico, Cenozoico, Quaternario, Pleistocenico, Superior.
Since data is a json file, using python and json lib we had decoded it:
import json
def decode_crono(crono_file):
with open(crono_file) as json_file:
data = json.load(json_file)
Now on we do not know how to treat it in a way to get what we need.
We can access keys like this:
k = data["Fanerozoico"]["Cenozoico"]["Quaternario "]["Pleistocenico "].keys()
or values like this:
v= data["Fanerozoico"]["Cenozoico"]["Quaternario "]["Pleistocenico "]["Superior"].values()
but this is still far from what we need.
{
"Fanerozoico": {
"id": "20000",
"Cenozoico": {
"id": "23000",
"Quaternario": {
"id": "23300",
"Pleistocenico": {
"id": "23310",
"Superior": {
"id": "23314"
},
"Medio": {
"id": "23313"
},
"Calabriano": {
"id": "23312"
},
"Gelasiano": {
"id": "23311"
}
}
}
}
}
}
It's a little hard to understand exactly what you are after here, but it seems like for some reason you have a bunch of nested json and you want to search it for an id and return a list that represents the path down the json nesting. If so, the quick and easy path is to recurse on the dictionary (that you got from json.load) and collect the keys as you go. When you find an 'id' key that matches the id you are searching for you are done. Here is some code that does that:
def all_keys(search_dict, key_id):
def _all_keys(search_dict, key_id, keys=None):
if not keys:
keys = []
for i in search_dict:
if search_dict[i] == key_id:
return keys + [i]
if isinstance(search_dict[i], dict):
potential_keys = _all_keys(search_dict[i], key_id, keys + [i])
if 'id' in potential_keys:
keys = potential_keys
break
return keys
return _all_keys(search_dict, key_id)[:-1]
The reason for the nested function is to strip off the 'id' key that would otherwise be on the end of the list.
This is really just to give you an idea of what a solution might look like. Beware the python recursion limit!
Based on the assumption that you need the full dictionary path until a key named id has a particular value, here's a recursive solution that iterates the whole dict. Bear in mind that:
The code is not optimized at all
For huge json objects it might yield StackOverflow :)
It will stop at first encountered value found (in theory there shouldn't be more than 1 if the json is semantically correct)
The code:
import json
from types import DictType
SEARCH_KEY_NAME = "id"
FOUND_FLAG = ()
CRONO_FILE = "a.jsn"
def decode_crono(crono_file):
with open(crono_file) as json_file:
return json.load(json_file)
def traverse_dict(dict_obj, value):
for key in dict_obj:
key_obj = dict_obj[key]
if key == SEARCH_KEY_NAME and key_obj == value:
return FOUND_FLAG
elif isinstance(key_obj, DictType):
inner = traverse_dict(key_obj, value)
if inner is not None:
return (key,) + inner
return None
if __name__ == "__main__":
value = "23314"
json_dict = decode_crono(CRONO_FILE)
result = traverse_dict(json_dict, value)
print result