Get dictionary value from multiple dictionaries in a list - python

I have a list of many dictionaries with only one key value pair like below.
List1 = [{'dept': 'a'}, {'country': 'India'}, {'name':'xyz'}, {'age':32}]
I want to extract name from this list by not using index number but with the dict key.
Can anyone help me out?

Try this:
List1 = [{'dept': 'a'}, {'country': 'India'}, {'name': 'xyz'}, {'age': 32}]
for dic in List1:
name = dic.get('name')
if name is not None: # {'name': ''} which is acceptable.
break
print(name)
output :
xyz

Or use list comprehesion. It always looks better than a loop.
[dic['name'] for dic in List1 if 'name' in dic][0]

Related

How to replace values in nested dictionaries by new values in a list in python

I am iterating through a list of dictionaries. I need to update the values for one specific key in all the dictionaries and I have the new values stored in a list. The list of new values is ordered so that the 1st new value belongs to a key in the 1st dictionary, 2nd new value to a key in the 2nd dictionary, etc.
My data looks something like this:
dict_list = [{'person':'Tom', 'job':'student'},
{'person':'John', 'job':'teacher'},
{'person':'Mary', 'job':'manager'}]
new_jobs = ['lecturer', 'cook', 'driver']
And I want to transform the list of dictionaries using the list of new jobs according to my description into this:
dict_list = [{'person':'Tom', 'job':'lecturer'},
{'person':'John', 'job':'cook'},
{'person':'Mary', 'job':'driver'}]
As I have a very long list of dictionaries I would like to define a function that would do this automatically but I am struggling how to do it with for loops and zip(), any suggestions?
I tried the for loop below. I guess the following code could work if it was possible to index the dictionaries like this dictionary['job'][i] Unfortunately dictionaries don't work like this as far as I know.
def update_dic_list():
for dictionary in dict_list:
for i in range(len(new_jobs)):
dictionary['job'] = new_jobs[i]
print(dict_list)
The output the code above gave me was this:
[{'person': 'Tom', 'job': 'driver'}, {'person': 'John', 'job': 'teacher'}, {'person': 'Mary', 'job': 'manager'}]
[{'person': 'Tom', 'job': 'driver'}, {'person': 'John', 'job': 'driver'}, {'person': 'Mary', 'job': 'manager'}]
[{'person': 'Tom', 'job': 'driver'}, {'person': 'John', 'job': 'driver'}, {'person': 'Mary', 'job': 'driver'}]
If your new_jobs list has the right job for each corresponding entry in the dict list, you could use zip:
dict_list = [{'person':'Tom', 'job':'student'},
{'person':'John', 'job':'teacher'},
{'person':'Mary', 'job':'manager'}]
new_jobs = ['lecturer', 'cook', 'driver']
for d, j in zip(dict_list, new_jobs):
d['job'] = j
print(dict_list)
prints
[{'person': 'Tom', 'job': 'lecturer'}, {'person': 'John', 'job': 'cook'}, {'person': 'Mary', 'job': 'driver'}]
With your loop, for each dictionary, you're going through the new jobs and updating that same dictionary over and over with each of the jobs until the last one. So by the end of it, they'll all be drivers. Because that's the last one.
You can do
dict_list = [{'person':'Tom', 'job':'student'},
{'person':'John', 'job':'teacher'},
{'person':'Mary', 'job':'manager'}]
new_jobs = ['lecturer', 'cook', 'driver']
def update_dic_list():
for job, _dict in zip(new_jobs, dict_list):
_dict['job'] = job
or
def update_dict_list():
for i, job in enumerate(new_jobs):
dict_list[i]['job'] = job
You only need to remove the inner loop because you are changing dictionary key job more than one time for each of item of outer loop:
def update_dic_list():
i = 0
for dictionary in dict_list:
dictionary['job'] = new_jobs[i]
i += 1
print(dict_list)
Or alternatively you could use enumerate:
def update_dic_list():
for i, dictionary in enumerate(dict_list):
dictionary['job'] = new_jobs[i]
print(dict_list)
Output:
[{'person': 'Tom', 'job': 'lecturer'}, {'person': 'John', 'job': 'cook'}, {'person': 'Mary', 'job': 'driver'}]

Creating a list of dictionaries from a list of list

I'm currently stuck facing some issue with creating a list of dictionaries from a list of lists.
I'm confused with how to append each dictionary to empty list(not in my code). I've known there should be some code after loop processing, but I wasn't able to find out what it is.
l_members = [['Jhon', '19', 'male'],
['Takeru', '20', 'male'],
['Yuri', '22', 'female']
]
d_members = {}
for i in range(len(l_members)):
d_members['name'] = l_members[i][0]
d_members['age'] = l_members[i][1]
d_members['sex'] = l_members[i][2]
l_members.append(d_members)
print(d_members)
Here's a result of print(d_members)
{'name': 'Yuri', 'age': '22', 'sex': 'female'}
my expectation of the result is like below
[{'name': 'Jhon', 'age': '19', 'sex': 'male'},
{'name': 'Takeru', 'age': '20', 'sex': 'male'},
{'name': 'Yuri', 'age': '22', 'sex': 'female'}]
I would appreciate your help, thanks:)
Maybe a list comprehension might work:
d_members = [
{ 'name': name, 'age': age, 'sex': sex }
for name, age, sex in l_members
]
print the list, not the dict you created print(l_members)
create d_members in the loop, to avoid using the same again and again
then reassign to the i box, don't append because it'll only add it
for i in range(len(l_members)):
d_members = {}
d_members['name'] = l_members[i][0]
d_members['age'] = l_members[i][1]
d_members['sex'] = l_members[i][2]
l_members[i] = d_members
print(l_members)
Here are some shorten ways with enumerate, I put some to show you the possiblities
for i in range(len(l_members)):
l_members[i] = {'name': l_members[i][0], 'age': l_members[i][1], 'sex': l_members[i][2]}
for i, member in enumerate(l_members):
l_members[i] = {'name': member[0], 'age': member[1], 'sex': member[2]}
for i, (name, age, sex) in enumerate(l_members):
l_members[i] = {'name': name, 'age': age, 'sex': sex}
You can also use a list-comprehension to avoid using the indices and rebuilt directly the list, along with dict+zip to create the dict :
l_members = [dict(zip(['name', 'age', 'sex'], member)) for member in l_members]
# another one
l_members = [{'name': name, 'age': age, 'sex': sex} for (name, age, sex) in l_members]
As I've mentioned in the comments, this is because your last line of code which prints the value actually prints the d_members variable which will be the last value of the for-loop. You should instead be printing out the l_members variable which you appended the values to in your for-loop.
Additionally, you'll robably find out that the previous records still exist when you print l_members, so you'll have to either:
Remove the initial entries once you're done with the for loop (using list slicing):
l_members = l_members[3:]
Override the value for each iteration of the for loop:
l_members[i] = d_members
Or store the results in a new variable:
ld_members = []
# in your for loop:
ld_members.append(d_members)
Just append the dict to a new list inside the loop as below
list_of_dicts = []
for i in range(len(l_members)):
d_members = {}
d_members['name'] = l_members[i][0]
d_members['age'] = l_members[i][1]
d_members['sex'] = l_members[i][2]
list_of_dicts.append(d_members)
print(list_of_dicts)

Write Values to Empty List of Dictionaries

I have a list of names of unknown length. I want to write the names with their corresponding key (name to an empty list of dictionaries).
Input:
names = ['john', 'bill']
Output:
[{'name': 'john'}, {'name': 'bill'}]
Here it is:
names = ['john', 'bill']
dic = [{'name': name} for name in names]
print(dic)
#[{'name': 'john'}, {'name': 'bill'}]

List of tuples to dictionary not working as expected

For some reason my small small brain is having problems with this, I have a list of tuples list = [('name:john','age:25','location:brazil'),('name:terry','age:32','location:acme')]. Im trying to move these values into a dictionary for parsing later. I have made a few attempts, below the latest of these and im not getting all results into the dict, the dict ends up with the last value iterated (its recreating the dict each time).
people = {}
list = [('name:john','age:25','location:brazil'),('name:terry','age:32','location:acme')]
for value in list:
people = {'person': [dict(item.split(":",1) for item in value)]}
You can try this one too:
inlist = [('name:john','age:25','location:brazil'),('name:terry','age:32','location:acme')]
d = []
for tup in inlist:
tempDict = {}
for elem in tup:
elem = elem.split(":")
tempDict.update({elem[0]:elem[1]})
d.append({'person':tempDict})
print(d)
Output:
[{'person': {'location': 'brazil', 'name': 'john', 'age': '25'}}, {'person': {'location': 'acme', 'name': 'terry', 'age': '32'}}]
If you want a dictionary with a key person and values the dictionaries with the people's info, then replace d.append({'person':tempDict}) with d.append(tempDict) and add d = {'person':d} right before printing.
Output:
{'person': [{'location': 'brazil', 'name': 'john', 'age': '25'}, {'location': 'acme', 'name': 'terry', 'age': '32'}]}
You can try this:
l = [('name:john','age:25','location:brazil'),('person:terry','age:32','location:acme')]
people = [{c:d for c, d in [i.split(':') for i in a]} for a in l]
Output:
[{'name': 'john', 'age': '25', 'location': 'brazil'}, {'person': 'terry', 'age': '32', 'location': 'acme'}]
First of all try not to call your list list. This name is protected in python and used usually to get a list out of iterators or ranges etc.
I would make a list of people first and then append each person to the people list as separate dictionary as follows:
people = []
my_list = [('name:john','age:25','location:brazil'),('person:terry','age:32','location:acme')]
for tup in my_list:
person = {}
for item in tup:
splitted = item.split(':')
person.update({splitted[0]:splitted[1]})
people.append(person)
The output then would be this:
[{'age': '25', 'location': 'brazil', 'name': 'john'},
{'age': '32', 'location': 'acme', 'person': 'terry'}]

Matching and Appending

I'm trying to figure out how to run 1 list through another list, and whenever the first names match, append it to the new list if it exists
list1 = [["Ryan","10"],["James","40"],["John","30"],["Jake","15"],["Adam","20"]]
list2 = [["Ryan","Canada"],["John","United States"],["Jake","Spain"]]
So it looks something like this.
list3 = [["Ryan","Canada","10"],["John","United States","30"],["Jake","Spain","15"]
So far I haven't really been able to even come close, so even the smallest guidance would be much appreciated. Thanks.
You could transform them into dictionaries and then use a list comprehension:
dic1 = dict(list1)
dic2 = dict(list2)
list3 = [[k,dic2[k],dic1[k]] for k in dic2 if k in dic1]
If ordering isn't a concern, the most straightforward way is to convert the lists into more suitable data structures: dictionaries.
ages = dict(list1)
countries = dict(list2)
That'll make it a cinch to combine the pieces of data:
>>> {name: [ages[name], countries[name]] for name in ages.keys() & countries.keys()}
{'Ryan': ['10', 'Canada'], 'Jake': ['15', 'Spain'], 'John': ['30', 'United States']}
Or even better, use nested dicts:
>>> {name: {'age': ages[name], 'country': countries[name]} for name in ages.keys() & countries.keys()}
{'Ryan': {'country': 'Canada', 'age': '10'},
'Jake': {'country': 'Spain', 'age': '15'},
'John': {'country': 'United States', 'age': '30'}}
If the names are unique you can make list1 into a dictionary and then loop through list2 adding items from this dictionary.
list1 = [["Ryan","10"],["James","40"],["John","30"],["Jake","15"],["Adam","20"]]
list2 = [["Ryan","Canada"],["John","United States"],["Jake","Spain"]]
list1_dict = dict(list1)
output = [item + [list1_dict[item[0]]] for item in list2]
If not, then you need to decide how to deal with cases of duplicate names.
You can use a set and an OrderedDict to combine the common names and keep order:
list1 = [["Ryan","10"],["James","40"],["John","30"],["Jake","15"],["Adam","20"]]
list2 = [["Ryan","Canada"],["John","United States"],["Jake","Spain"]]
from collections import OrderedDict
# get set of names from list2
names = set(name for name,_ in list2)
# create an OrderedDict using name as key and full sublist as value
# filtering out names that are not also in list2
d = OrderedDict((sub[0], sub) for sub in list1 if sub[0] in names)
for name, country in list2:
if name in d:
# add country from each sublist with common name
d[name].append(country)
print(d.values()) # list(d.values()) for python3
[['Ryan', '10', 'Canada'], ['John', '30', 'United States'], ['Jake', '15', 'Spain']]
If list2 always has common names you can remove the if name in d:

Categories

Resources