access nested data in json - python

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"])

Related

Converting two complex dictionary list to a dictionary

suppose I have two dictionary list below:
all=[]
lis1={
'code':'matata',
'commandes':[
{
'date':'12-10-22',
'content':[
{
'article':'Article1',
'designation':'Designe1',
'quantity':5
}
]
}
]
}
lis2={
'code':'fropm',
'commandes':[
{
'date':'04-08-21',
'content':[
{
'article':'Article2',
'designation':'Designe2',
'quantity':3
}
]
}
]
}
Now I add at list level my two dictionaries
all.append(list1)
all.append(liste2)
to replace the [..] in {..} for a single list we can do all[0]
But after adding the two lists and then doing all[0] we only have the first list whose [..] whose square brackets are replaced by {..}
I would like to have this rendering { {...}, {...} }
Is this possible??
You need to refine what you are trying to accomplish. lis1 is a dict, not a list. lis1['commandes'] is a list containing a single dict, but presumably in the general case it might have more. Each of those has a key "date" and another key "content", which is again a list of dicts ....
An arbitrary example would be to add the commandes from lis2 to those in lis1:
lis1['commandes'].extend( lis2['commandes'] )
which is using the list .extend() method to join two lists. It should yield
{
'code':'matata',
'commandes':[
{
'date':'12-10-22',
'content':[
{
'article':'Article1',
'designation':'Designe1',
'quantity':5
}
]
},
{
'date':'04-08-21',
'content':[
{
'article':'Article2',
'designation':'Designe2',
'quantity':3
}
]
}
]
}
"Drilling down" is just a matter of supplying array indices and dict keys as appropriate. for example,
lis1['commandes'][0]['content'][0]['quantity']
will be 5.
Added in response to comment:
Building such a structire is step-by-step. Remember that in Python, assignment is name-binding. So names referring to lists and dicts are a lot like pointers in other languages. You mutate the objects referred to in memory (if they are mutable, which lists and dicts are).
So something like:
lis = {}
lis['code'] = 'example'
lis['commandes'] = []
for foo in something:
lis['commandes'] .append( build_command( foo))
...
def build_command(foo):
command = {}
date = datetime.date.today()
command['date'] = datetime.datetime.now().strftime('%d-%m-%y')
command['content'] = []
for # iterating over something ...
content = {}
content['article'] =
content['designation'] =
content['quantity'] =
command['content'].append( content)
return command

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

How can I get the dates from this nested list in Python

My data contains nested lists and I am trying to create a list that contains only the date information from the second layer of nested lists.
"DateMap": {
"2020-12-04:0": {
"55.0": [
{
}]},
"2020-12-11:7": {
"60.0": [
{
}]}
}
I want to get a list that is like this mylist = ["2020-12-04:0", "2020-12-11:7"]
I have looked into using regex and list comprehensions and this is the expression I have found to match the dates ^\d{4}-\d\d-\d\d:\d\d?$
How can I make this work?
Use the function .keys(). This just gets all the keys of a dictionary, which is exactly what you're looking for. If DateMap is inside a dictionary, say dic, just do the same thing for dic["DateMap"].
DateMap = {
"2020-12-04:0": {
"55.0": [
{
}]},
"2020-12-11:7": {
"60.0": [
{
}]}
}
mylist = DateMap.keys()
# mylist = list(DateMap.keys()) for Python 3
print(mylist)
# Prints ['2020-12-04:0', '2020-12-11:7']

python: a list comprehension over a list of dictionaries of list of dictionary items

I know this is a worst title but let me explain the question by sample. My data is:
data = [
{
"subdata": [ # subdata various number of dictionaries of same keys, including "ext_id", ...
{
"ext_id": "12345", # ... but of different values
...
},
{
"ext_id": "54321",
...
}
],
...
},
... # and many other dictionary items with "subdata", which in turn contains
# a list of dictionaries containing "ext_id" and corresponding values
]
my goal is make a list of the pair of "ext_id"s in "subdata", i.e.
goal = [
("12345", "54321"),
(...)
]
I know a for-loop is okay for this goal, but wondering if a list comprehension is possible? I tried this:
goal = [x["ext_id"] for y in data for x in y["subdata"]]
and get a flattened version of goal ["12345", "54321", ...] rather than a 2-D list.
Any advices are appreciated.
If you have a data structure like this:
data = [
{
"subdata": [
{
"ext_id": "12345",
},
{
"ext_id": "54321",
}
],
},
{
"subdata": [
{
"ext_id": "98765",
},
{
"ext_id": "56789",
}
],
}
]
Then to get the output that you want, you could use list comprehension (and a generator comprehension too) as follows:
goal = [tuple(dict_['ext_id'] for dict_ in subdata['subdata']) for subdata in data ]
goal will contain:
[('12345', '54321'), ('98765', '56789')]
Yes you can use list comprehension here. Following code will give you your desired results
[tuple(sub_dict.get('ext_id') for sub_dict in dictionary.get('subdata')) for dictionary in data]

How to extract a specific key's value from a nested dictionary in python and return a list of the values

Say I have a dictionary that looks like this:
SOURCE_IDENTIFIERS = {
Sources.app1.name: {
"schema_suffixes": ["something", "something2"],
"identifier_name": "id1"
},
Sources.app2.name: {
"database_name": "app2",
"identifier_name": "id2"
},
"ALL": {
"identifier_name": "email"
}
}
I eventually want a list that looks like this:
["id1", "id2", "email"]
How do I get this info?
Use a list comprehension over the values (which are dictionaries with a common key):
[d["identifier_name"] for d in SOURCE_IDENTIFIERS.values()]
This works because each value in SOURCE_IDENTIFIERS is a dictionary with at least the identifier_name key.
Note that unless you use Python 3.6 or newer, you can't count on iteration over SOURCE_IDENTIFIERS.values() to produce the nested dictionaries in a specific order.

Categories

Resources