Nested Dictionary in Python and updating specific key inside a key - python

I am trying to update a specific key in python but it appears that all the keys that are similar are also updated.
inner_dict = {'grade': None, 'age': None, 'genre': None}
outer_dict = {'Sam': inner_dict, 'Joe': inner_dict, 'Some' : inner_dict}
outer_dict['Sam']['age'] = 10
I expect to have this as an output:
{'Sam': {'grade': None, 'age': 10, 'genre': None}, 'Joe': {'grade': None, 'age': None, 'genre': None}, 'Some': {'grade': None, 'age': None, 'genre': None}}
But instead I have this:
{'Sam': {'grade': None, 'age': 10, 'genre': None}, 'Joe': {'grade': None, 'age': 10, 'genre': None}, 'Some': {'grade': None, 'age': 10, 'genre': None}}
in which the ages for all the kids are updated to 10

You have to copy the object, otherwise you have only one single object with 3 references to them.
So the solution is:
outer_dict = {'Sam': inner_dict.copy(), 'Joe': inner_dict.copy(), 'Some' : inner_dict.copy()}

Because you define the dict using the same inner dict 3 times, the three are all references to the same dict; modifying one modifies all three.

This happens because inner_dict is an object and all three are references to the same object. You can fix this by forcing python to create new objects for each entry with the .copy() method:
inner_dict = {'grade': None, 'age': None, 'genre': None}
outer_dict = {'Sam': inner_dict.copy(), 'Joe': inner_dict.copy(), 'Some' : inner_dict.copy()}
outer_dict['Sam']['age'] = 10

Related

How to get value from list of dictionaries based on specific key value which does not exist in all dictionaries?

I have a list of dictionaries that is like this:
{'name': ['Sam'], 'where': ['London']},
{'name': ['Jon'], 'where': ['NY']},
{'name': ['Jon'], 'hobby': ['fifa']},
{'Age': ['20'], 'Country': ['US']},
I do have a dictionary like this that could have a lot of same keys but a lot doesn't have that key too. As in above example, we have name key in first 3, but we don't have name key in the 4th. I am trying to get a list of all values that has key 'name'.
Thanks
What you want is unclear (nor the link to pandas or numpy).
If you simply want the values of name when those exist:
l = [{'name': ['Sam'], 'where': ['London']},
{'name': ['Jon'], 'where': ['NY']},
{'name': ['Jon'], 'hobby': ['fifa']},
{'Age': ['20'], 'Country': ['US']},]
out = [d['name'] for d in l if 'name' in d]
# [['Sam'], ['Jon'], ['Jon']]
# or as flat list
out = [name for d in l if 'name' in d for name in d['name']]
# ['Sam', 'Jon', 'Jon']
# or just the first name
out = [d['name'][0] for d in l if 'name' in d]
# ['Sam', 'Jon', 'Jon']
Here is a way to extract all names:
data = [
{'name': ['Sam'], 'where': ['London']},
{'name': ['Jon'], 'where': ['NY']},
{'name': ['Jon'], 'hobby': ['fifa']},
{'Age': ['20'], 'Country': ['US']},
]
names = [item['name'][0] for item in data if 'name' in item]
print(names)
Result:
['Sam', 'Jon', 'Jon']
I assume your data is a list of dicts.
data = [{'name': ['Sam'], 'where': ['London']},
{'name': ['Jon'], 'where': ['NY']},
{'name': ['Jon'], 'hobby': ['fifa']},
{'Age': ['20'], 'Country': ['US']},]
You can get a sub list of all elements with a name key like this:
output = [elem for elem in data if elem.get("name")]
There are many ways to do this. One would be:
_list = [{'name': ['Sam'], 'where': ['London']},
{'name': ['Jon'], 'where': ['NY']},
{'name': ['Jon'], 'hobby': ['fifa']},
{'Age': ['20'], 'Country': ['US']}]
print(*(name for d in _list if (name := d.get('name'))))
Output:
['Sam'] ['Jon'] ['Jon']
You can try a list expression:
all_dicts = [{'name': ['Sam'], 'where': ['London']},
{'name': ['Jon'], 'where': ['NY']},
{'name': ['Jon'], 'hobby': ['fifa']},
{'Age': ['20'], 'Country': ['US']}]
dicts_with_name = [d.values() for d in all_dicts if 'name' in d.keys() ]
This extracts all values (for all keys) of those dictionaries in the list that have a name field. If you want the key, value pairs, you can d.items() instead of d.values()

how to insert list of elements into list of dictionaries

I have one list of elements and another list of dictionaries and i want to insert list of elements into each dictionary of list
list_elem = [1,2,3]
dict_ele = [{"Name":"Madhu","Age":25},{"Name":"Raju","Age:24},{""Name":"Mani","Age":12}],
OUTPUT As:
[{"ID":1,"Name":"Madhu","Age":25},{"ID":2,"Name":"Raju","Age:24},{"ID":3,"Name":"Mani","Age":12}]
I have tried this way :
dit = [{"id":item[0]} for item in zip(sam)]
# [{"id":1,"id":2,"id":3}]
dic1 = list(zip(dit,data))
print(dic1)
# [({"id":1},{{"Name":"Madhu","Age":25}},{"id":2},{"Name":"Raju","Age:24},{"id":3},{""Name":"Mani","Age":12})]
What is the most efficient way to do this in Python?
Making an assumption here that the OP's original question has a typo in the definition of dict_ele and also that list_elem isn't really necessary.
dict_ele = [{"Name":"Madhu","Age":25},{"Name":"Raju","Age":24},{"Name":"Mani","Age":12}]
dit = [{'ID': id_, **d} for id_, d in enumerate(dict_ele, 1)]
print(dit)
Output:
[{'ID': 1, 'Name': 'Madhu', 'Age': 25}, {'ID': 2, 'Name': 'Raju', 'Age': 24}, {'ID': 3, 'Name': 'Mani', 'Age': 12}]
dict_ele = [{"Name":"Madhu","Age":25},{"Name":"Raju","Age":24},{"Name":"Mani","Age":12}]
list_elem = [1,2,3]
[{'ID': id, **_dict} for id, _dict in zip(list_elem, dict_ele)]
[{'ID': 1, 'Name': 'Madhu', 'Age': 25}, {'ID': 2, 'Name': 'Raju', 'Age': 24}, {'ID': 3, 'Name': 'Mani', 'Age': 12}]
try this: r = [{'id':e[0], **e[1]} for e in zip(list_elem, dict_ele)]

Find element in a list of dicts based on value

I am trying to find an element in a list, how can I do that? This is what I wrote:
user_list = [
{'name': 'Alizom_12',
'gender': 'f',
'age': 34,
'active_day': 170},
{'name': 'Xzt4f',
'gender': None,
'age': None,
'active_day': 1152},
{'name': 'TomZ',
'gender': 'm',
'age': 24,
'active_day': 15},
{'name': 'Zxd975',
'gender': None,
'age': 44,
'active_day': 752},
]
def find_user(user_name):
for items in user_list:
if user_name == 'name':
print(user_name+" exists")
else:
print(user_name+" does not exists")
when I print the following I want it to find the user:
find_user('Alizom_12')
You're close. You need to get the value in the dictionary
if user_name == items['name']:
user_list = [
{'name': 'Alizom_12',
'gender': 'f',
'age': 34,
'active_day': 170},
{'name': 'Xzt4f',
'gender': None,
'age': None,
'active_day': 1152},
{'name': 'TomZ',
'gender': 'm',
'age': 24,
'active_day': 15},
{'name': 'Zxd975',
'gender': None,
'age': 44,
'active_day': 752},
]
def find_user(user_name):
userExists = False
for items in user_list:
for key, value in items.items():
if key == 'name' and value == user_name:
userExists = True
if userExists is True:
print(user_name+" exists")
else:
print(user_name+" does not exists")
find_user('Alizom_12')
There are more than one places that your code has to be fixed:
Let's try to use the code snippet to point out them one by one.
First you can find the user_name by go through each dict. and the key name, secondly, it's better to return and not print.
Lastly, the last print should be out side of the for-loop, otherwise, you will get many repeated not found messages...
def find_user(user_name):
for items in user_list:
if items['name'] == user_name:
return f'{user_name} exists. '
#return items # will return this user's dict. (all info) *You have to comment prev. statement first. and uncomment this
return f'{user_name} - does not exists'
print(find_user('Alizom_12')) # Alizom_12 exists.
print(find_user('John Doe')) # John Doe - does not exists

Creating a dictionary from a json list of arrays

I'm trying to create a dictionary of specific key values from a list of dictionaries. I believe my code is not flattening out the dictionaries when i put in chunkdata.extend(pythondict[0][1][2], chunkdata will return with the whole 1st 2nd and 3rd dictionaries where i want something like the "name" key pair for all the dictionaries that return in the response.
chunkdata = []
for chunk in chunklist:
url3 = "some URL"
headers = {'accept': 'application/json',
response = requests.request("GET", url3, headers=headers)
time.sleep(5)
print(response.text)
pythondict = json.loads(response.text)
print(pythondict)
chunkdata.extend(pythondict['name']['age']['date']
pythondict output
[{'data': {'name': 'jon', 'age': '30', 'date': '2020-01-05', 'time': '1', 'color': 'blue'}, {'data': {'name': 'phil', 'age': '33', 'date': '2020-01-05', 'time': '1', 'color': 'blue'}, {'data': {'name': 'ted', 'age': '25', 'date': '2020-01-05', 'time':'1', 'color': 'blue'}]
Traceback (most recent call last):
File line 84, in <module>
chunkdata.extend(pythondict['name']['age']['date']
TypeError: list indices must be integers or slices, not str
Use requests.json() for parsing. It is more reliable and accurate.
Note: Response header MUST contain Content-Type: application/json in the header in order for .json() method to work
I figured out that the json format you get is not right here. I was not able to make out the necessity of the 'data:' prior to each element.
It would be better to modify it in the following form:
python_dict=[{'name': 'jon', 'age': '30', 'date': '2020-01-05', 'time': '1', 'color': 'blue'}, {'name': 'phil', 'age': '33', 'date': '2020-01-05', 'time': '1', 'color': 'blue'}, {'name': 'ted', 'age': '25', 'date': '2020-01-05', 'time':'1', 'color': 'blue'}]
Modify the relevant part of the code as follows:
chunkdata=[]
for x in range(len(python_dict)):
temp_list=[python_dict[x]['name'],python_dict[x]['age'],python_dict[x]['date'],python_dict[x]['time'],python_dict[x]['color']]
chunkdata.append(temp_list)
print(chunkdata)
chunkdata will be a list of lists that you can keep appending into. The output for chunkdata is as follows:
[['jon', '30', '2020-01-05', '1', 'blue'], ['phil', '33',
'2020-01-05', '1', 'blue'], ['ted', '25', '2020-01-05', '1', 'blue']]

compare two different length lists of dictionaries in python

I want to compare below dictionaries. Name key in the dictionary is common in both dictionaries.
If Name matched in both the dictionaries, i wanted to do some other stuff with the data.
PerfData = [
{'Name': 'abc', 'Type': 'Ex1', 'Access': 'N1', 'perfStatus':'Latest Perf', 'Comments': '07/12/2017 S/W Version'},
{'Name': 'xyz', 'Type': 'Ex1', 'Access': 'N2', 'perfStatus':'Latest Perf', 'Comments': '11/12/2017 S/W Version upgrade failed'},
{'Name': 'efg', 'Type': 'Cust1', 'Access': 'A1', 'perfStatus':'Old Perf', 'Comments': '11/10/2017 S/W Version upgrade failed, test data is active'}
]
beatData = [
{'Name': 'efg', 'Status': 'Latest', 'rcvd-timestamp': '1516756202.632'},
{'Name': 'abc', 'Status': 'Latest', 'rcvd-timestamp': '1516756202.896'}
]
Thanks
Rajeev
l = [{'name': 'abc'}, {'name': 'xyz'}]
k = [{'name': 'a'}, {'name': 'abc'}]
[i['name'] for i in l for f in k if i['name'] == f['name']]
Hope above logic work for you.
The answer provided didn't assign the result to any variable. If you want to print it, add the following would work:
result = [i['name'] for i in l for f in k if i['name'] == f['name']]
print(result)

Categories