Merge/Concatenate two dictionaries (/tuples) with same keys python - python

I have two json objects represented as a dictionary and I want to concatenate both into one and the last will be a json.
At the moment I have:
obj1 = {
"FS":11440000,
"BW":76000000,
"Gain":62,
"Fc":70000000,
"real":[ 4,2,3,],
"imag":[1,1,3,],
}
obj2 = {
"FS":61440000,
"BW":56000000,
"Gain":62,
"Fc":80000000,
"real":[ 1,2,3,],
"imag":[1,2,3,],
}
I want to have:
[
{
[
{
"FS":61440000,
"BW":56000000,
"Gain":62,
"Fc":70000000,
"real":[ 1,2,3,],
"imag":[1,2,3,],
},
{
"FS":61440000,
"BW":56000000,
"N":8192,
"Gain":62,
"Fc":80000000,
"real":[ 1,2,3,],
"imag":[1,2,3,],
}
],
"ts":1231234165234,
"scale":[10000,-45],
"N":8192,
},
]
How to join obj1 + obj2 and remain the keys and not update them? I need all of them as you can see the final output I'm trying to create.
After concatenating obj1 and obj2 into one I need to add 3 more keys.
I'm using python 3.6.

The dict output you expect is badly formatted, so you will never be able to make it. (dicts needs key for each value - even if value can be list).
foo = {"foo": "value"}
bar = {"bar": "value"}
data = {"ts": "...", "scale": [10000, -45], "N": 8192, "data": [foo, bar]}
Would gives you a dict where you can access data via data['data']

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

Looking up a value in a nested dictionary to get a value in a separate dictionary but same parent dictionary

In the response that comes back from an API request. I get a format that is a list of nested dictionaries. for example.
{
"data": [
{
"3": {
"value": 1
},
"6": {
"value": "Conversion"
},
"7": {
"value": "HVAC"
}
},
I can easily get past the the first dictionary using r['data']. At this point, each list item is a record in a database. r['data'][0] gives me a dictionary of what the field ('3') is and then a dictionary of what the value is ({'value': 'Conversion'}).
I want to be able to look up a value like 'Conversion' and have it tell me what the value is for field '3'. Anyway to do this using python?
Your description doesn't quite fit with reality. Let's have a complete structure:
r = {
"data": [
{
"3": {
"value": 1
},
"6": {
"value": "Conversion"
},
"7": {
"value": "HVAC"
}
}
]
}
r is a dictionary. It contains a single key ('data') whose associated value is a list which, in this example, contains one dictionary. That dictionary has 3 keys - "3", "6" and "7". Each of those keys has a value which itself is a dictionary comprised of a single key ('value') and, obviously, an associated value.
You can assert as follows:
assert r['data'][0]['6']['value'] == 'Conversion'
Hopefully that shows how you can access the lower level value(s)
What's unclear from your question is why would you be searching for 'Conversion' when you want the value from key '3' which would be:
r['data'][0]['3']['value']
EDIT:
def get_value(r, from_key, ref_key, value):
for d in r['data']:
if d.get(from_key, {}).get('value') == value:
return d.get(ref_key, {}).get('value')
print(get_value(r, '6', '3', 'Conversion'))
Doing it this way offers the flexibility of specifying the relevant keys and value
I have to make an assumption that what you are trying to say is that you want the index based on the value.
r = {...} # your data
def lookup(val, r_data):
for i in range(len(r_data['data'])): #loops through list based on index
for k, v in r_data['data'][i].items(): #loops dict with key/value
if v['value'] == val: #checks if value matches needle
return "[{}][{}]".format(i, k)
This returns '[0][6]'. I don't know if your data is supposed to be formatted that way... a list within 'data' and then only one dict inside. But, given this format, this will give you the index.

Updating dictionary values using zip() in python

I have 4 lists of floats which I have extracted from a JSON file. I have to modify the values in these 4 lists simultaneously, depending on the first list. I am using zip() to iterate over all the 4 lists, but I am unable to update the values in the original dictionary representing the JSON.
I need to check the sign of an element in first list, if it is negative, all the values in the 4 lists which have the same index as that element have to be zeroed out. The following code snippet contains some sample data:
{
"channels": [
{
"name": "TTZAR1e",
"samples": [
{
"data": [0.0996781, 0.0177724, -0.00566106],
"modifiers": [
{"data": [0.084338, 0.0103356, 0.010294], "type": "staterror"},
{"data": {"hi_data": [0.0996781, 0.0177724, -0.00566106], "lo_data": [0.0996781, 0.0177724, -0.00566106]}, "type": "histosys"}
],
"name": "conv"
}
]
}
]
}
And here's what I've tried so far:
import json
file = open("test1.json", 'r')
json_data = json.load(file)
for key, value in json_data.items():
for i in value:
for samp in i.get('samples'):
for mod in samp.get('modifiers'):
hi_list=[]
lo_list=[]
if(mod.get('type') == 'staterror'):
stat_list = mod.get('data')
if(mod.get('type') == 'histosys'):
hi_list = mod.get('data').get('hi_data')
lo_list = mod.get('data').get('lo_data')
for val, val2, val3, val4 in zip(samp.get('data'), hi_list, lo_list, stat_list):
if (val<0):
val,val2,val3,val4 = 0,0,0,0
When I print the JSON, I still get the original negative values. The final output I am working towards is something like the following:
{
"channels": [
{
"name": "TTZAR1e",
"samples": [
{
"data": [0.0996781, 0.0177724, 0],
"modifiers": [
{"data": [0.084338, 0.0103356, 0],"type": "staterror"},
{"data": {"hi_data": [0.0996781, 0.0177724, 0], "lo_data": [0.0996781, 0.0177724, 0]}, "type": "histosys"}
],
"name": "conv"
}
]
}
]
}
I would like to know how to update the values in the dictionary itself. Is there a way to implement this here?
zip() creates a list of tuples. These tuples do not share any memory with the original lists, meaning that you have no way of mutating the inputs to zip() using what it returns.
You should store references to the lists that you want to modify, and then modify them in-place. (I will note that you should seriously consider simplifying this code, as the high nesting depth makes this code hard to read and debug.) Here's a code snippet that does that:
for key, value in json_data.items():
for i in value:
for samp in i.get('samples'):
lists_to_modify = [samp.get('data')]
for mod in samp.get('modifiers'):
if(mod.get('type') == 'staterror'):
lists_to_modify.append(mod.get('data'))
if(mod.get('type') == 'histosys'):
lists_to_modify.append(mod.get('data').get('hi_data'))
lists_to_modify.append(mod.get('data').get('lo_data'))
for data_index in range(len(samp.get('data'))):
if samp.get('data')[data_index] < 0:
for list_to_modify in lists_to_modify:
list_to_modify[data_index] = 0

Forming a JSON Arrays with Objects using a Python object

I have a some variables that I need to dump as a json of the format:
{
"elements":[
{
"key":"foo",
"value":"7837"
},
{
"key":"bar",
"value":"3423"
}
]
}
I am trying to figure out the right object which would give the above structure upon usin json.dumps(). I see that in python, lists give a json array where as dictionaries give a json object while using json dumps.
I am trying something like:
x={}
x["elements"]={}
x["elements"]["key"]="foo"
x["elements"]["value"]="7837"
x["elements"]["key"]="bar"
x["elements"]["value"]="3423"
json_x=json.dumps(x)
But this still gives me:
{"elements": {"key": "bar", "value": "3423"}}
which is obviously incorrect.
How to I incorporate the correct dictionary and list structure to get to the above json?
Why don't you just use literal?
x = {
"elements": [
{"key":"foo", "value":"7837"},
{"key":"bar", "value":"3423"}
]
}
To fix your code, you need to use a list literal ([]) when assigning to elements dictionary entry:
>>> x = {}
>>> x["elements"] = [] # <---
>>> x["elements"].append({})
>>> x["elements"].append({})
>>> x["elements"][0]["key"]="foo"
>>> x["elements"][0]["value"]="7837"
>>> x["elements"][1]["key"]="bar"
>>> x["elements"][1]["value"]="3423"
>>> json.dumps(x)
'{"elements": [{"value": "7837", "key": "foo"}, {"value": "3423", "key": "bar"}]}'
But, it's hard to read, maintain.

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