how to delete empty dict inside list of dictionary? - python

How can I remove empty dict from list of dict as,
{
"ages":[{"age":25,"job":"teacher"},
{},{},
{"age":35,"job":"clerk"}
]
}
I am beginner to python.
Thanks in advance.

Try this
In [50]: mydict = {
....: "ages":[{"age":25,"job":"teacher"},
....: {},{},
....: {"age":35,"job":"clerk"}
....: ]
....: }
In [51]: mydict = {"ages":[i for i in mydict["ages"] if i]}
In [52]: mydict
Out[52]: {'ages': [{'age': 25, 'job': 'teacher'}, {'age': 35, 'job': 'clerk'}]}
OR simply use filter
>>>mylist = [{'age': 25, 'job': 'teacher'}, {}, {}, {'age': 35, 'job': 'clerk'}]
>>>filter(None, mylist)
[{'age': 25, 'job': 'teacher'}, {'age': 35, 'job': 'clerk'}]
So in your dict, apply it as
{
"ages":filter(None, [{"age":25,"job":"teacher"},
{},{},
{"age":35,"job":"clerk"}
])
}

There's a even simpler and more intuitive way than filter, and it works in Python 2 and Python 3:
You can do a "truth value testing" on a dict to test if it's empty or not:
>>> foo = {}
>>> if foo:
... print(foo)
...
>>>
>>> bar = {'key':'value'}
>>> if bar:
... print(bar)
...
{'key':'value'}
Therefore you can iterate over mylist and test for empty dicts with an if-statement:
>>> mylist = [{'age': 25, 'job': 'teacher'}, {}, {}, {'age': 35, 'job': 'clerk'}]
>>> [i for i in mylist if i]
[{'age': 25, 'job': 'teacher'}, {'age': 35, 'job': 'clerk'}]

If you are using Python 3, simply do:
list(filter(None, your_list_name))
This removes all empty dicts from your list.

This while loop will keep looping while there's a {} in the list and remove each one until there's none left.
while {} in dictList:
dictList.remove({})

You may try the following function:
def trimmer(data):
if type(data) is dict:
new_data = {}
for key in data:
if data[key]:
new_data[key] = trimmer(data[key])
return new_data
elif type(data) is list:
new_data = []
for index in range(len(data)):
if data[index]:
new_data.append(trimmer(data[index]))
return new_data
else:
return data
This will trim
{
"ages":[{"age":25,"job":"teacher"},
{},{},
{"age":35,"job":"clerk"}
]
}
and even
{'ages': [
{'age': 25, 'job': 'teacher', 'empty_four': []},
[], {},
{'age': 35, 'job': 'clerk', 'empty_five': []}],
'empty_one': [], 'empty_two': '',
'empty_three': {}
}
to this:
{'ages': [{'age': 25, 'job': 'teacher'}, {'age': 35, 'job': 'clerk'}]}

You can also try this
mylist = [{'age': 25, 'job': 'teacher'}, {}, {}, {'age': 35, 'job': 'clerk'}]
mylist=[i for i in mylist if i]
print(mylist)
Output:
[{'age': 25, 'job': 'teacher'}, {'age': 35, 'job': 'clerk'}]

Related

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)]

How can I collect key-value pairs of dictionaries into one large dictionary in Python?

I have a dictionary in the following format:
data = {
'Bob': {
'age': 12,
'weight': 150,
'eye_color': 'blue'
},
'Jim': {
'favorite_food': 'cherries',
'sport': 'baseball',
'hobby': 'running'
},
'Tom': {
'strength': 'average',
'endurance': 'high',
'heart_rate': 'low'
}
}
What is the most Pythonic way to concatenate all of the dictionaries within dict into a new dictionary so that I would end up with something like the following:
new_dict = {
'age': 12,
'weight': 150,
'eye_color': 'blue',
'favorite_food': 'cherries',
'sport': 'baseball',
'hobby': 'running',
'strength': 'average',
'endurance': 'high',
'heart_rate': 'low'
}
You can use functools.reduce() to build up the result, unioning one dictionary at a time:
from functools import reduce
data = {
'Bob' : { 'age': 12, 'weight': 150, 'eye_color': 'blue' },
'Jim' : { 'favorite_food': 'cherries', 'sport': 'baseball', 'hobby': 'running' },
'Tom' : { 'strength': 'average', 'endurance': 'high', 'hear_rate': 'low' }
}
result = reduce(lambda x, y: dict(**x, **y), data.values(), {})
print(result)
This outputs:
{'age': 12, 'weight': 150, 'eye_color': 'blue', 'favorite_food': 'cherries',
'sport': 'baseball', 'hobby': 'running', 'strength': 'average',
'endurance': 'high', 'hear_rate': 'low'}
On Python 3.9 or higher, you can use lambda x: x | y, operator.or_, or dict.__or__ instead of lambda x: dict(**x, **y) if you're on Python 3.9 or higher. The latter two are from a suggestion by Mad Physicist.
One option is to use a dictionary comprehension with a nested generator expression:
new_dict = {k: v for d in data.values() for k, v in d.items()}
Another way that's subtly different to to use collections.ChainMap:
new_dict = collections. ChainMap(*data.values())
In this case, new_dict will not be a dict, but will quack like one just fine. Lookup will be a bit slower, but construction will be faster.

Python convert multiple lists to dictionary

I have 3 lists:
names = ["john", "paul", "george", "ringo"]
job = ["guitar", "bass", "guitar", "drums"]
status = ["dead", "alive", "dead", "alive"]
I am trying to figure out the best way to combine these lists into a dict like the following:
{"person":{"Name":"john", "Job":"guitar", "Status":"dead"}, "person":{"Name":"paul", "Job":"bass", "Status":"alive"}, "person":{"Name":"george", "Job":"guitar", "Status":"dead"}, "person":{"Name":"ringo", "Job":"drums", "Status":"alive"}}
I have tried using dict(zip) but cannot get it to format like above.
Thanks in advance!
I think what you want is a list of dictionaries. You can zip your three lists together and use a list comprehension. Here's an example:
[
{'name': name, 'job': job, 'status': status}
for name, job, status in zip(names, jobs, statuses)
]
(also renaming your job to jobs and status to statuses)
Which will give you:
[
{'name': 'john', 'job': 'guitar', 'status': 'dead'},
{'name': 'paul', 'job': 'bass', 'status': 'alive'},
{'name': 'george', 'job': 'guitar', 'status': 'dead'},
{'name': 'ringo', 'job': 'drums', 'status': 'alive'}
]
I think this is what you are looking for:
>>> names = ["john", "paul", "george", "ringo"]
>>> job = ["guitar", "bass", "guitar", "drums"]
>>> status = ["dead", "alive", "dead", "alive"]
>>> persons = []
>>> for n, j, s in zip(names, job, status):
... person = { 'name': n, 'job': j, 'status': s }
... persons.append(person)
...
>>> persons
[{'status': 'dead', 'job': 'guitar', 'name': 'john'}, {'status': 'alive', 'job': 'bass', 'name': 'paul'}, {'status': 'dead', 'job': 'guitar', 'name': 'george'}, {'status': 'alive', 'job': 'drums', 'name': 'ringo'}]
>>>
Try this approach:
names = ["john", "paul", "george", "ringo"]
job = ["guitar", "bass", "guitar", "drums"]
status = ["dead", "alive", "dead", "alive"]
two step process:
description =[{'job': j, 'status': s} for j,s in zip(job,status)]
artist ={n: i for n,i in zip(names,description)}}
final output:
print(artist)
{'john': {'job': 'guitar', 'status': 'dead'},
'paul': {'job': 'bass', 'status': 'alive'},
'george': {'job': 'guitar', 'status': 'dead'},
'ringo': {'job': 'drums', 'status': 'alive'}}
you can then do something like this:
artist['ringo']['job']
output:
'drums'

Modifying keys and values in nested dictionaries in python

I'm working with a nested dictionary and I'm trying to figure out how to modify certain nested and non-nested keys/values effectively. In short, I'm trying to do the following:
take a nested value and switch it with a non-nested key
rename a nested key.
Here's a basic example of a dictionary that I'm working with:
pet_dictionary = {'Buford':{'color':'white', 'weight': 95, 'age':'3',
'breed':'bulldog'},
'Henley':{'color':'blue', 'weight': 70, 'age':'2',
'breed':'bulldog'},
'Emi':{'color':'lilac', 'weight': 65, 'age':'1',
'breed':'bulldog'},
}
I want to take the non-nested key, which is name of each dog (i.e. Buford, Henley, Emi), switch it with nested value for the age (i.e. 3, 2, 1), and then change the nested key name from 'age' to 'name.' So the output should look like this:
pet_dictionary = {'3':{'color':'white', 'weight': 95, 'name':'Buford',
'breed':'bulldog'},
'2':{'color':'blue', 'weight': 70, 'name':'Henley',
'breed':'bulldog'},
'1':{'color':'lilac', 'weight': 65, 'name':'Emi',
'breed':'bulldog'},
}
I understand how to do this manually one-by-one, but I'm not sure what the best approach is for making all of these changes in a more elegant/optimal way.
While iterating your dictionary, you can cleanly build a new dictionary in three steps:
# Preserves original dict
d = {}
for k, v in pet_dictionary.items():
key = v["age"] # 1. grab the new key
d[key] = {"name": k} # 2. add new "name" item
d[key].update({k_:v_ for k_, v_ in v.items() if k_!="age"}) # 3. update the new dict
d
This might help
pet_dictionary = {'Buford':{'color':'white', 'weight': 95, 'age':'3',
'breed':'bulldog'},
'Henley':{'color':'blue', 'weight': 70, 'age':'2',
'breed':'bulldog'},
'Emi':{'color':'lilac', 'weight': 65, 'age':'1',
'breed':'bulldog'},
}
d = {}
for k,v in pet_dictionary.items():
d[v['age']] = pet_dictionary[k]
d[v['age']].update({"name": k})
del d[v['age']]['age']
print d
Output:
{'1': {'color': 'lilac', 'breed': 'bulldog', 'name': 'Emi', 'weight': 65}, '3': {'color': 'white', 'breed': 'bulldog', 'name': 'Buford', 'weight': 95}, '2': {'color': 'blue', 'breed': 'bulldog', 'name': 'Henley', 'weight': 70}}
This is a situation where pythons iterables come to shine
p = {'Buford':{'color':'white', 'weight': 95, 'age':'3',
'breed':'bulldog'},
'Henley':{'color':'blue', 'weight': 70, 'age':'2',
'breed':'bulldog'},
'Emi':{'color':'lilac', 'weight': 65, 'age':'1',
'breed':'bulldog'},
}
new_dictionary = {p[i]['age']:{'color':p[i]['color'],'weight':p[i]['weight'],
'name':i,'breed':p[i]['breed']} for i in p}
Output:
{'3': {'color': 'white', 'weight': 95, 'name': 'Buford', 'breed': 'bulldog'},
'2': {'color': 'blue', 'weight': 70, 'name': 'Henley', 'breed': 'bulldog'},
'1': {'color': 'lilac', 'weight': 65, 'name': 'Emi', 'breed': 'bulldog'}}
With a couple of comprehensions, you can do that transformation like:
Code:
new_dict = {
info['age']: {k: v for k, v in list(info.items()) + [('name', name)]
if k != 'age'}
for name, info in pet_dictionary.items()
}
Test Code:
pet_dictionary = {
'Buford': {'color': 'white', 'weight': 95, 'age': '3', 'breed': 'bulldog'},
'Henley': {'color': 'blue', 'weight': 70, 'age': '2', 'breed': 'bulldog'},
'Emi': {'color': 'lilac', 'weight': 65, 'age': '1', 'breed': 'bulldog'},
}
new_dict = {
info['age']: {k: v for k, v in list(info.items()) + [('name', name)]
if k != 'age'}
for name, info in pet_dictionary.items()
}
for dog in new_dict.items():
print(dog)
Results:
('3', {'color': 'white', 'weight': 95, 'breed': 'bulldog', 'name': 'Buford'})
('2', {'color': 'blue', 'weight': 70, 'breed': 'bulldog', 'name': 'Henley'})
('1', {'color': 'lilac', 'weight': 65, 'breed': 'bulldog', 'name': 'Emi'})
With pandas,
import pandas as pd
pet_dictionary = {'Buford':{'color':'white', 'weight': 95, 'age':'3',
'breed':'bulldog'},
'Henley':{'color':'blue', 'weight': 70, 'age':'2',
'breed':'bulldog'},
'Emi':{'color':'lilac', 'weight': 65, 'age':'1',
'breed':'bulldog'},
}
pd.DataFrame.from_dict(pet_dictionary, orient='index') \
.reset_index() \
.rename(columns={'index': 'name'}) \
.set_index('age') \
.to_dict('index')
def flip(k, v):
v1 = dict(v)
v1.update(name=k)
return v1.pop('age'), v1
pet_dictionary2 = dict([flip(k, v) for k, v in pet_dictionary.items()])
# import pprint as pp; pp.pprint(pet_dictionary2)
# {'1': {'breed': 'bulldog', 'color': 'lilac', 'name': 'Emi', 'weight': 65},
# '2': {'breed': 'bulldog', 'color': 'blue', 'name': 'Henley', 'weight': 70},
# '3': {'breed': 'bulldog', 'color': 'white', 'name': 'Buford', 'weight': 95}}
If it is ok to change the previous dictionary, then you can do:
def flip(k, v):
v.update(name=k)
return v.pop('age'), v
Doing this in few lines, without any additional libs, but mutating original dictionary:
pet_dictionary = {
nested.pop('age'): nested.update({'name': name}) or nested
for name, nested in pet_dictionary.items()
}
And with additional import, but without mutating pet_dictionary:
import copy
new_pet_dict = {
nested.pop('age'): nested.update({'name': name}) or nested
for name, nested in copy.deepcopy(pet_dictionary).items()
}
...which leaves original pet_dictionary untouched.
Info
Initially, I published different answer, where key in new dict where created using .pop method, and nested dict using {**nested, 'name': name} but it didn't work. It would be much cleaner solution, but AFAIK, interpreter reads code from right to left and... that's obviously wouldn't work using this approach.
How does this work then? It looks little tricky, especially line:
nested.update({'name': name}) or nested
But let's have a closer look. We need nested to be updated with name key, but that returns None and mutates object. So left part of this or will be always None and we would like to have dict object in our dict comprehension. Here comes short circuit evaluation in Python, which always returns second operand if first is falsy.
None-mutating example uses deepcopy and mutates ad-hoc copy, not original dictionary.
Update for Python 3.8:
Only if mutating original dict is acceptable (credits to #pylang for noticing it), there is neat syntax for playing with dictionaries:
new = {nested.pop('age'): {**nested, 'name': name} for name, nested in pet_dictionary.items()}
Here's a two liner:
##add new value, which was formerly the key
{k: v.update({'name':k}) for k,v in pet_dictionary.items()}
##reset keys to value of 'age'
new_pet = {v.get('age'): v for k,v in pet_dictionary.items()}

How to update a list that contains values as dictionaries?

Hi frens I have the following form of data
fields = [{'name':'xxx', 'age':24, 'location':'city_name'},
{'name':'yyy', 'age':24, 'location':'city_name'}]
Now I want to update the location in two dicts and the save the fields in the same format.How to do it?I am beginner.
Set same location for both fields.
>>> fields = [{'name':'xxx', 'age':24, 'location':'city_name'},
... {'name':'yyy', 'age':24, 'location':'city_name'}]
>>> for field in fields:
... field['location'] = 'loc'
...
>>> fields
[{'age': 24, 'name': 'xxx', 'location': 'loc'}, {'age': 24, 'name': 'yyy', 'location': 'loc'}]
To set different locations, use zip:
>>> for field, loc in zip(fields, ['here', 'there']):
... field['location'] = loc
...
>>> fields
[{'age': 24, 'name': 'xxx', 'location': 'here'}, {'age': 24, 'name': 'yyy', 'location': 'there'}]

Categories