Get an element of a list where something is static - python

I'm using an API where the request.json gives me back a list inside a list inside a list inside a list.
I recently got an answer how to access these lists and their elements.
However I don't know a way to get a specific list.
So it's like this:
{
"name1": {
},
"name2": {
"something1": 213,
"something2": [
{
"info1": 123,
"info2": 324
}
]
}
}
and i need to get info1 which is a variable from a list where info2 is which is static and does not change.
There's 10 "somethings" and info2 is an id.
How can I check for info2 while trying to get info1?
I used this to get info1:
r.json()['name2']['something2'][0]['info1']
but i need 'something2' to be match 'info2'
Basically I need info1 from somethingX where info2 = xyz(set known value)
r.json()['name2']['something2'][0]['info1']
always gives me the 1st item of the 'name2'

Loop through the dictionary elements.
data = r.json()['name2']
For val in data.values():
if val['info2'] == xyz:
print(val['info1'])
break

Related

How to get a key from inside another key in python

Hey does anybody know how I would go about getting the value of a key which is already inside another key like this:
a = {"fruit":[{"oranges":['10']},{"apples":['11']}]}
print(a.get("fruit"))
I can get the value of "fruit" but how would I get the value of "oranges".
Thank you for any help in advance.
Let's format your dictionary and clearly see what you have:
a = {
"fruit": [
{
"oranges": ['10']
},
{
"apples": ['11']
}
]
}
So, a.get('fruit') gives you a list, which elements can be accessed with indexes.
So a['fruit'][0] gives you
{
"oranges": ['10']
}
and a['fruit'][1] gives you
{
"apples": ['11']
}
So in order to get the value of oranges you should go with:
a['fruit'][0]['oranges']
which will give you: ['10']. ['10'] is a list of its own. If you want to get only the value, you can do:
a['fruit'][0]['oranges'][0]
You just have to access the first element of the list inside fruits, and then access the key inside
print(a['fruit'][0]['oranges']

Iterate through a nested python dict

I have a JSON file that looks like this:
{
"returnCode": 200,
"message": "OK",
“people”: [
{
“details: {
"first": “joe”,
“last”: doe,
“id”: 1234567,
},
“otheDetails”: {
“employeeNum”: “0000111222”,
“res”: “USA”,
“address”: “123 main street”,
},
“moreDetails”: {
“family”: “yes”,
“siblings”: “no”,
“home”: “USA”,
},
},
{
“details: {
"first": “jane”,
“last”: doe,
“id”: 987654321,
},
“otheDetails”: {
“employeeNum”: “222333444”,
“res”: “UK”,
“address”: “321 nottingham dr”,
},
“moreDetails”: {
“family”: “yes”,
“siblings”: “yes”,
“home”: “UK,
},
}
This shows two entries, but really there are hundreds or more. I do not know the number of entries at the time the code is run.
My goal is to iterate through each entry and get the 'id' under "details". I load the JSON into a python dict named 'data' and am able to get the first 'id' by:
data['people'][0]['details']['id']
I can then get the second 'id' by incrementing the '0' to '1'. I know I can set i = 0 and then increment i, but since I do not know the number of entries, this does not work. Is there a better way?
Less pythonic then a list comprehension, but a simple for loop will work here.
You can first calculate the number of people in the people list and then loop over the list, pulling out each id at each iteration:
id_list = []
for i in range(len(data['people'])):
id_list.append(data['people'][i]['details']['id'])
You can use dict.get method in a list comprehension to avoid getting a KeyError on id. This way, you can fill dictionaries without ids with None:
ids = [dct['details'].get('id') for dct in data['people']]
If you still get KeyError, then that probably means some dcts in data['people'] don't have details key. In that case, it might be better to wrap this exercise in try/except. You may also want to identify which dcts don't have details key, which can be gathered using error_dct list (which you can uncomment out from below).
ids = []
#error_dct = []
for dct in data['people']:
try:
ids.append(dct['details']['id'])
except KeyError:
ids.append(None)
#error_dct.append(dct)
Output:
1234567
987654321

Nested dictionary access is returning a list

The issue I'm having is that when i try to access the values within a nested dictionary, i cannot because it's returning a list instead of a dictionary.
I have a .json file with this format;
{
"users": [
{
"1": {
"1": "value",
"2": "value"
}
}
]
}
I load the .json file, and access the value i want by using this function
def load_json(fn):
with open(fn) as pf:
data = json.load(pf)
return data['users']['1']['2']
If i simply do return data it is a dictionary, but if try to access further by adding ['users'], it turns into a list and will give an index error if i try to access key #1 or #2 inside of that..
My objective is to obtain the value of the nested key #2 for example, ideally without having loop through it.
Your JSON contains an array (Python list) wrapping the inner dicts (that's what the [ and ] in your JSON indicate). All you need to do is change:
return data['users']['1']['2']
to:
return data['users'][0]['1']['2']
# ^^^ Added
to index the list to get into the inner dicts.
given your data structure, and following it down :
data is a dictionary - with one key 'users' and a value of a list
data['users'] is a list - with one entry
data['users'][0] is a dictionary - with one key '1' and a value of a dictionary
data['users'][0][1] is a dictionary - with two keys '1' and '2'
So you need to do do :
def load_json(fn):
with open(fn) as pf:
data = json.load(pf)
return data['users'][0]['1']['2']

Getting specific field values from Json Python

I have a JSON file, and what I am trying to do is getting this specific field '_id'. Problem is that when I use json.load('input_file'), it says that my variable data is a list, not a dictionary, so I can't do something like:
for value in data['_id']:
print(data['_id'][i])
because I keep getting this error: TypeError: list indices must be integers or slices, not str
What I also tried to do is:
data = json.load(input_file)[0]
It kinda works. Now, my type is a dictionary, and I can access like this: data['_id']
But I only get the first '_id' from the archive...
So, what I would like to do is add all '_id' 's values into a list, to use later.
input_file = open('input_file.txt')
data = json.load(input_file)[0]
print(data['_id'])# only shows me the first '_id' value
Thanks for the help!
[{
"_id": "5436e3abbae478396759f0cf",
"name": "ISIC_0000000",
"updated": "2015-02-23T02:48:17.495000+00:00"
},
{
"_id": "5436e3acbae478396759f0d1",
"name": "ISIC_0000001",
"updated": "2015-02-23T02:48:27.455000+00:00"
},
{
"_id": "5436e3acbae478396759f0d3",
"name": "ISIC_0000002",
"updated": "2015-02-23T02:48:37.249000+00:00"
},
{
"_id": "5436e3acbae478396759f0d5",
"name": "ISIC_0000003",
"updated": "2015-02-23T02:48:46.021000+00:00"
}]
You want to print the _id of each element of your json list, so let's do it by simply iterating over the elements:
input_file = open('input_file.txt')
data = json.load(input_file) # get the data list
for element in data: # iterate on each element of the list
# element is a dict
id = element['_id'] # get the id
print(id) # print it
If you want to transform the list of elements into a list of ids for later use, you can use list comprehension:
ids = [ e['_id'] for e in data ] # get id from each element and create a list of them
As you can see the data is a list of dictionaries
for looping over data you need to use the following code
for each in data:
print each['_id']
print each['name']
print each['updated']
it says that my variable data is a list, not a dictionary, so I can't do something like:
for value in data['_id']:
print(data['_id'][i])
Yes, but you can loop over all the dictionaries in your list and get the values for their '_id' keys. This can be done in a single line using list comprehension:
data = json.load(input_file)
ids = [value['_id'] for value in data]
print(ids)
['5436e3abbae478396759f0cf', '5436e3acbae478396759f0d1', '5436e3acbae478396759f0d3', '5436e3acbae478396759f0d5']
Another way to achieve this is using the map built-in function of python:
ids = map(lambda value: value['_id'], data)
This creates a function that returns the value of the key _id from a dictionary using a lambda expression and then returns a list with the return value from this function applied on every item in data

access nested data in json

I want to retrieve all the IP address range from Azure cloud from here
The data after conversion in json is in the following format:
{
"AzurePublicIpAddresses": {
"Region": [
{
...
"IpRange": [
{
"_Subnet": "40.69.96.0/19"
},
{
"_Subnet": "40.86.192.0/18"
}
],
"_Name": "canadaeast"
},
{
"IpRange": [
{
"_Subnet": "13.71.160.0/19"
},
{
"_Subnet": "13.88.224.0/19"
},
{
"_Subnet": "40.85.192.0/18"
}
],
"_Name": "canadacentral"
}
],
"_xmlns:xsd": "http://www.w3.org/2001/XMLSchema",
"_xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance"
}
}
I am unable to access IP ranges? through this code?
with open('AZURE_IP.json') as data_file:
data = json.load(data_file)
list_IPCIDR = []
for i in data["AzurePublicIpAddresses"]:
for ii in i["Region"]:
for j in ii["IpRange"]:
list_IPCIDR.append(i["_Subnet"])
sys.stdout=open("test2.txt","w")
data["AzurePublicIpAddresses"] is a dict. Iterating directly over a dict just gives you the the keys of that dict.
So
for i in data["AzurePublicIpAddresses"]:
print(i)
will print
Region
_xmlns:xsd
_xmlns:xsi
in some order.
You can get the Subnet IP ranges like this:
list_IPCIDR = []
for ipr in data["AzurePublicIpAddresses"]["Region"]:
for d in ipr["IpRange"]:
list_IPCIDR.append(d["_Subnet"])
print(list_IPCIDR)
output
['40.69.96.0/19', '40.86.192.0/18', '13.71.160.0/19', '13.88.224.0/19', '40.85.192.0/18']
This works because data["AzurePublicIpAddresses"]["Region"] is a list of dicts. Each of those dict (that are temporarily bound to the name ipr) contains a list of dicts associated with the "IpRange" key, so we need to iterate over those lists in the inner loop, and then extract the subnet strings from those inner dicts.
If you like you can do this in a list comprehension, butI advise splitting it up over several lines, eg:
list_IPCIDR = [d["_Subnet"]
for ipr in data["AzurePublicIpAddresses"]["Region"]
for d in ipr["IpRange"]]
It's often desirable to iterate over the (key, value) pairs of a dict. You can do that using the .items method (or .iteritems in Python 2). Eg,
list_IPCIDR = []
for key, val in data["AzurePublicIpAddresses"].items():
if key == "Region":
for dct in val:
for s in dct["IpRange"]:
list_IPCIDR.append(s["_Subnet"])
AzurePublicIpAddresses is a dictionary, so:
for i in data["AzurePublicIpAddresses"]:
Iterates through the keys (which are strings, in this case). I.e. you're trying to do "Region"["Region"], which is string slicing. Try something more like:
for i in data["AzurePublicIpAddresses"]:
for ii in data["Azure..."][i]:
# Use ii as it is the contents of the 'Region' attribute
if type(ii) == list: # Sometimes ii is a string, like at the end of your data.
list_IPCIDR.append(ii["IpRange"]["_Subnet"])

Categories

Resources