Adding terms to Python dictionary - python

I have the following valid dictionary. I'm trying to add another group of terms under the "expansion_modules" group.
lan_router = {
'HOSTNAME1':{
'system_type': 'MDF',
'chassis':{
0:{
'model_num': 'EX4550',
'vc_role': 'MASTER',
'expansion_modules':{
1:{
'pic_slot': 1,
'expan_model': 'EX4550VCP'
}
},
'built-in_modules':{
0:{
'pic_slot': 2,
'built-in_model': 'EX4550BI'
}
}
}
}
}
}
I want to add the following under "expansion_modules" without removing "1"...
2:{'pic_slot': 2, 'expan_model': 'EX4550SFP'}
The following code adds what I want, but removes the existing term...
print lan_router['HOSTNAME1']['chassis'][0]['expansion_modules'][1]['expan_model']
lan_router['HOSTNAME1']['chassis'][0]['expansion_modules'] = { 2: {} }
lan_router['HOSTNAME1']['chassis'][0]['expansion_modules'][2] = {'pic_slot' : 1, 'expan_model' : 'EX45504XSFP'}

You do not need the line - lan_router['HOSTNAME1']['chassis'][0]['expansion_modules'] = { 2: {} } , it is replacing the dictionary inside expansion_modules , just remove this and execute rest.
Code -
print lan_router['HOSTNAME1']['chassis'][0]['expansion_modules'][1]['expan_model']
lan_router['HOSTNAME1']['chassis'][0]['expansion_modules'][2] = {'pic_slot' : 1, 'expan_model' : 'EX45504XSFP'}

Access it like this:
lan_router['HOSTNAME1']['chassis'][0]['expansion_modules'][2] = {}

Anand's answer is correct as it answers your question.
I would add that often dictionaries with [0, 1, ...] as keys should be just lists. Instead of:
'expansion_modules':{
1:{
'pic_slot': 1,
'expan_model': 'EX4550VCP'
},
2:{ ... }
}
perhaps you should have:
'expansion_modules':[
{
'pic_slot': 1,
'expan_model': 'EX4550VCP'
},
{ ... }
]

Related

Why doesn't pymongo MongoDB return an exact value in find_one()?

I want to retrieve the single value "count "from pymongo DB but it is not working. The image below shows how the data entry is setup.
Here is the call to my Database class to use the db.find_one().
CODE HERE:
filters = {"email": session.get('email')}
returns = {f'words.{today_s}.{self.length - 3}.count': 1}
count_value = Database.find_one_return_one("users", filters, returns)
print({f'words.{today_s}.{self.length - 3}.count':1})
print(count_value)
#staticmethod
def find_one_return_one(collection: str, query: Dict, data: Dict) -> Dict:
return Database.DATABASE[collection].find_one(query, data)
This returns an empty list of dictionaries from the correct data? I want the count value returned.
This is the projection query: {words.20220302.0.count : 1}
This is what is returned:
{'_id': ObjectId('621ee5065d08c44070140df0'), 'words': {'20220302': [{}, {}, {}, {}, {}, {}, {}]}}
What is wrong or is there a better quicker way to retrieve the count value?
The following query projection can be used to get the desired result. Note this worked with MongoDB v5.
A sample document; similar to the one in the question post:
{ _id: 1, words: { fld: [ { a: 1, b: 2 }, { a: 9, b: 100 } ] } }
The expected result is: { "_id" : 1, "words" : { "fld" : { "a" : 9 } } }
The query:
INDEX = 1 # this is the index of the array element
query = { }
projection = {
'words.fld': {
'$arrayElemAt': [
{ '$map': { 'input': '$words.fld', 'in': { 'a': '$$this.a' } } },
INDEX
]
}
}
result = collection.find_one(query, projection)
print(result)

Converting snake_case to lowerCamelCase

I have defined a dataclass in which all variable are in snake_case. Whereas when I am returning my object I want to return everything in lowerCamerCase. But the problem is then nesting is very deep. Is there any way to automate this.
Although I have defined upper response object in camelCase what can I do for others.
#My json looks like
{
"highLevelObj1" : {
"low_level_obj1" : 1,
"low_level_obj2" : 2
},
"someRandomText" : {
"some_random_info1" : 1,
"some_random_info2" : 2
}
}
My expected output is
{
"highLevelObj1" : {
"lowLevelObj1" : 1,
"lowLevelObj2" : 2
},
"someRandomText" : {
"someRandomInfo1" : 1,
"someRandomInfo2" : 2
}
}
We can define a method to convert a snake_case string to a lowerCamelCase string
(source), then I think the easiest way would be to convert your json into a string convert it to camelCase then convert it back to a dictionary
import json
def to_camel_case(snake_str):
components = snake_str.split('_')
return components[0] + ''.join(x.title() for x in components[1:])
my_dict = {
"highLevelObj1" : {
"low_level_obj1" : 1,
"low_level_obj2" : 2
},
"someRandomText" : {
"some_random_info1" : 1,
"some_random_info2" : 2
}
}
string_dict = json.dumps(my_dict)
string_dict_camel_case = to_camel_case(string_dict)
my_dict = json.loads(string_dict_camel_case)
Output :
{'highLevelObj1': {'lowLevelObj1': 1, 'LowLevelObj2': 2},
'Somerandomtext': {'SomeRandomInfo1': 1, 'SomeRandomInfo2': 2}}

How to add key to existing dictionary?

I am using python3 and trying to figure out the easiest way to add another layer to my dictionary. I have a dictionary that looks like this.
{ "block1": ["brian"], "block2": ["angel"], "block3": ["sally"] }
How can I add name into the existing dictionary?
{ "name": { "block1": [ "brian" ], "block2": [ "angel" ], "block3": [ "sally" ] } }
d1 = { "block1": ["brian"], "block2": ["angel"], "block3": ["sally"] }
d1 = {"name":d1}
print (d1)

Pull key from json file when values is known (groovy or python)

Is there any way to pull the key from JSON if the only thing I know is the value? (In groovy or python)
An example:
I know the "_number" value and I need a key.
So let's say, known _number is 2 and as an output, I should get dsf34f43f34f34f
{
"id": "8e37ecadf4908f79d58080e6ddbc",
"project": "some_project",
"branch": "master",
"current_revision": "3rtgfgdfg2fdsf",
"revisions": {
"43g5g534534rf34f43f": {
"_number": 3,
"created": "2019-04-16 09:03:07.459000000",
"uploader": {
"_account_id": 4
},
"description": "Rebase"
},
"dsf34f43f34f34f": {
"_number": 2,
"created": "2019-04-02 10:54:14.682000000",
"uploader": {
"_account_id": 2
},
"description": "Rebase"
}
}
}
With Groovy:
def json = new groovy.json.JsonSlurper().parse("x.json" as File)
println(json.revisions.findResult{ it.value._number==2 ? it.key : null })
// => dsf34f43f34f34f
Python 3: (assuming that data is saved in data.json):
import json
with open('data.json') as f:
json_data = json.load(f)
for rev, revdata in json_data['revisions'].items():
if revdata['_number'] == 2:
print(rev)
Prints all revs where _number equals 2.
using dict-comprehension:
print({k for k,v in d['revisions'].items() if v.get('_number') == 2})
OUTPUT:
{'dsf34f43f34f34f'}

Update key without affecting the key's values within a nested dictionary

I am trying to update a key while retaining its values within a nested dictionaries.
While I have found a method to do so, I had to create new dictionaries in order to cater for it. As such, wondering if there anyone could provide me with a better insight on the approach I have taken?
init_dict = {
'pageA' : {
0 : {
'menuA' : [
'a01',
'a02'
]
}
},
'pageB' : {
1 : {
'menuB' : [
'b10'
]
}
}
}
changed = {'pageB' : 0, 'pageA' : 1}
condense_dict = {}
for k, v in init_dict.items():
for i in v.keys():
condense_dict[k] = init_dict[k][i]
new_dict = {}
for i in condense_dict:
new_dict[i] = {}
new_dict[i][changed.get(i)] = condense_dict.get(i)
My expected output is as follows:
{
'pageA' : {
1 : {
'menuA' : [
'a01',
'a02'
]
}
},
'pageB' : {
0 : {
'menuB' : [
'b10'
]
}
}
}
You can pop the presumably only key from the sub-dict and assign it to the new key for each entry in changed:
for k, v in changed.items():
init_dict[k][v] = init_dict[k].pop(next(iter(init_dict[k])))
init_dict becomes:
{'pageA': {1: {'menuA': ['a01', 'a02']}}, 'pageB': {0: {'menuB': ['b10']}}}
Using the .pop() method this can be done similar to this (although I'm sure you could rewrite it better)
init_dict = {
'pageA': {
0: {
'menuA' : [
'a01',
'a02'
]
}
},
'pageB': {
1: {
'menuB': [
'b10'
]
}
}
}
print(init_dict)
thing = init_dict.pop('pageA')
sub_thing = thing.pop(0)
redone = {1: sub_thing}
init_dict.update({'pageA': redone})
print(init_dict)
{'pageA': {0: {'menuA': ['a01', 'a02']}}, 'pageB': {1: {'menuB': ['b10']}}}
{'pageA': {1: {'menuA': ['a01', 'a02']}}, 'pageB': {1: {'menuB': ['b10']}}}
You can see it's the same data as we start with, but we changed 0 to 1
Here I use .pop() and change it inplace. With the same init_dict as you:
change_to = {1: 0, 0: 1}
for k, v in init_dict.items():
for old_key in v.keys():
if old_key in change_to:
v[change_to[old_key]] = v.pop(old_key)

Categories

Resources