for the first part
app_dict = {}
app_dict['properties'] = { "name": "test" }
if a key doesn't exist, it will be created, you initially defined app_dict = {} as a dictionary object, hence app_dict['properties'] = { "name": "test" } is valid because it created a properties key and assigned the content as another dictionary {'name': 'test'}
for the second part
app_dict = {}
app_dict['properties']['version'] = {"name":"dino"}
the app_dict['properties'] doesn't exist yet so it's not a dictionary , hence assigning app_dict['properties']['version'] = {"name":"dino"} will thrown an error KeyError: 'properties'.
if you have done it this way
app_dict = {}
app_dict['properties'] = { "name": "test" }
app_dict['properties']['version'] = {"name":"dino"}
This would have worked , because app_dict['properties'] is already created as it's declared as a dictionary , hence app_dict['properties']['version'] = {"name":"dino"} will only create a key in the dictionary assigning it to another dictionary