Converting two complex dictionary list to a dictionary - python

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

Related

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.

Retreive JSON Keys In Python

My goal is to iterate through every element in classes and add the value of class in classes into a new list.
JSON Structure:
{
"images": [
{
"classifiers": [
{
"classes": [
{
"class": "street",
"score": 0.846
},
{
"class": "road",
"score": 0.85
}
]
}
]
}
]
}
In the above JSON example, the new list should contain:
{'street','road'}
I tried to iterate over json_data['images'][0]['classifiers']['classes'] and for each one list.append() the value of class.
list = list()
def func(json_data):
for item in json_data['images'][0]['classifiers']['classes']:
list.append(item['class'])
return(list)
I am receiving a TypeError which is:
TypeError: list indices must be integers or slices, not str
What I am getting from this TypeError is that it attempts to add a string to the list but list.append() does not accept a string as a paramet. I need to somehow convert the string into something else.
My question is what should I convert the string into so that list.append() will accept it as a parameter?
The first issue is that classifiers is also a list, so you need an additional index to get at classes. This will work:
for item in json_data['images'][0]['classifiers'][0]['classes']:
Second, you want the result as a set not a list, so you can do: return set(lst). Note that sets are unordered, so don't expect the ordering of items to match that of the list.

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