Using list comprehension to create nested dictionary with empty lists - python

I want to create a dictionary with dictionaries with empty lists inside. The nested dictionaries all have the same keys.
I have a solution already; but I really don't think it is smart:
outer_keys = ['out_a', 'out_b', 'out_c']
inner_keys = ['in_a', 'in_b', 'in_c']
dictionary = {}
for o in outer_keys:
dictionary[o] = {}
for i in inner_keys:
dictionary[o][i] = list()
This one works.
The result is:
{'out_a':
{'in_a': [],
'in_b': [],
'in_c': []},
{'out_b':
{'in_a': [],
'in_b': [],
'in_c': []},
{'out_c':
{'in_a': [],
'in_b': [],
'in_c': []}}
But is there a way to do it in a single line?
I tried
dictionary = dict([(o, {i: list()}) for o in outer_keys for i in inner_keys])
which unfortunately only saves the last inner_key and leads to:
{'out_a':
{'in_c': []},
'out_b':
{'in_c': []},
'out_c':
{'in_c': []}}

You can used a nested dict comprehension - the outer comprehension creates the dictionary, and for each key in it, another inner comprehension creates the inner dictionary
dictionary = {o: {i:list() for i in inner_keys} for o in outer_keys}

Related

Appending to Nested Dictionary with Identical Keys

I have a list containing values that should be used as keys for a dictionary. Right now the list to be converted to keys looks like the following:
myList = ["A", "B"]
I am converting this list to be the keys to a dictionary by doing the following:
newDict = dict.fromkeys(myList, {"Min":[], "Max":[], "Avg":[]})
When printing newDict I get the output:
{'A': {'Min': [], 'Max': [], 'Avg': []}, 'B': {'Min': [], 'Max': [], 'Avg': []}}
However, when trying to write to the newDict["B"]["Avg"] list, the value gets added to both the "A" and "B" keys:
Code:
newDict["B"]["Avg"].append(111)
Output:
{'A': {'Min': [], 'Max': [], 'Avg': [111]}, 'B': {'Min': [], 'Max': [], 'Avg': [111]}}
Is there for the appended value to only be added to the intended key?
This comes a lot when handling arrays and dicts.
What I prefer to do is use list/dict comprehensions to initialize a new object every time.
newDict = {k: {"Min":[], "Max":[], "Avg":[]} for k in myList}
With the initial method, your keys are pointing at the same object with the same id. You may briefly check this with a simple
newDict['A'] is newDict['B'] # True
class names can be camelCase, but not variables. Maybe pep8 will help you further in your journey through python. Thank you.
That's because both the keys are given the value {"Min":[], "Max":[], "Avg":[]}, which is the one dict in both case, rather than two identical dicts.
You can verify by calling id on each dict.
[id(v) for v in newDict.values()] # gives [4618156608, 4618156608]
Or as #FlorianAendekerk suggested, with is
newDict["A"] is newDict["B"] # gives True
You can fix it by creating a new dictionnary for each key for instance with a dict comprehenssion:
newDict = {k: {"Min":[], "Max":[], "Avg":[]} for k in myList}
PS. you should check out PEP8 as variables are not suposed to be camelCase or PascalCase.

How can I create an empty triple nested dictionary using dictionary comprehension?

I have three lists that I would like to make into keys for an empty triple nested dictionary using dictionary comprehension. "Facility" is the outer key, "Products" is the middle key, and "Customer" is the inner key. How can I do this? Thanks in advance
Here are my lists that need to be made into keys:
Facility = ['Fac-1', 'Fac-2','Fac-3','Fac-4','Fac-5']
Products = ['45906','48402','80591','102795','107275','128067','129522',]
Customer = ["Apple","Samsung","Huawei","Nokia","Motorolla"]
If by empty dict, you mean to have empty lists as values.
You could do that with a dict comprehension:
>>> d = {f: {p: {c: [] for c in Customer} for p in Products} for f in Facility}
Then you will get the data structure you described:
>>> d
{'Fac-1': {'102795': {'Apple': [], ...}, ...},
'Fac-2': {'102795': {'Apple': [], ...}, ...},
...}
>>> d.keys()
dict_keys(['Fac-1', 'Fac-2', 'Fac-3', 'Fac-4', 'Fac-5'])
>>> d['Fac-1'].keys()
dict_keys(['45906', '48402', '80591', '102795', '107275', '128067', '129522'])
>>> d['Fac-1']['45906'].keys()
dict_keys(['Apple', 'Samsung', 'Huawei', 'Nokia', 'Motorolla'])

How to remove dict where certain key is None

I want to delete a dictionary where certain key is None.
For example I have a list of dictionaries like:
my = [{"mydata": ""}, {"mydata": "hello"}]
What I did is:
for my_list in my:
if my_list["mydata"] == "":
my_list.clear()
But this gives:
[{}, {'mydata': 'hello'}]
I want that {} empty dictionary to be removed, How can I achieve it ?
My desired result format is :
{"my_data": "hello"}
Try this:
my = [{"mydata":""},{"mydata":"hello"}]
my2=[x for x in my if x['mydata']!='']
print(my2)
try list comprehension with any or all depending on your usecase.
In the example given by you if there is only one key in the dict then all and any won't make much difference.
my = [{"mydata":""},{"mydata":"hello"}]
my_new = [i for i in my if any(i.values())] #[{'mydata': 'hello'}]
Use List Comprehension
my = [{"mydata": ""}, {"mydata": "hello"}, {"mydata": "bye"}, {"mydata": ""}]
new_my = [{x: y} for i in my for x,y in i.items() if y != ""]
print(new_my)
[{'mydata': 'hello'}, {'mydata': 'bye'}]
Use remove() rather than clear(), and iterate over a copy of the list to avoid issues
for my_list in my[:]:
if my_list["mydata"] == "":
my.remove(my_list)

Need help to remove empty lists from dictionaries

I have this dictionary:
a_dict = {1: "hello", 2: [], 3: [], 4: "hey", 5:"phone"}
And I want to remove all the empty lists from this dictionary.
Output: a_dict = {1:"hello",4:"hey",5:"phone"}
I tried this:
for item in a_dict:
if a_dict[item] == []:
del item
However, this just gives back the original dictionary. It doesn't do anything to it.
You should not be deleting key of a dict while you are iterating it. You can save your keys in some other variable and use it to delete keys. Here is a solution very much similar to your current code.
deleteKeys = []
for item in a_dict:
if a_dict[item] == []:
deleteKeys.append(item)
for i in deleteKeys:
del a_dict[i]

Get the values of a dictionary as list of values

I'm trying to obtain the values that are stored inside a dict but I couldn't do it.
dict = {"user": {"tw_id": [["1080231111188251398"], ["1080111112808902656"], [], ["1080081111173306369"], [], ["1080491111114200192"]]}}
I tried list(map(...) but I got a list of the characters as a result.
Please help!
I want to get a list like this:
list = ["1080231111188251398","1080111112808902656","1080081111173306369","1080491111114200192"]
Thank you
See How to make a flat list out of list of lists? For example:
# Using simpler data for readability
d = {"user": {"tw_id": [["a"], ["b"], [], ["c"], [], ["d"]]}}
from itertools import chain
L = list(chain.from_iterable(d['user']['tw_id']))
print(L) # -> ['a', 'b', 'c', 'd']
BTW don't use variable names like dict and list since they shadow the builtin types dict and list.
You can use a simple list comprehension to flatten, which accesses the first item of each subarray (assuming each subarray will only ever contain 1 item):
lst = [i[0] for i in dct["user"]["tw_id"] if i]
>>> dct = {"user": {"tw_id": [["1080231111188251398"], ["1080111112808902656"], [], ["1080081111173306369"], [], ["1080491111114200192"]]}}
>>> lst = [i[0] for i in dct["user"]["tw_id"] if i]
>>> lst
['1080231111188251398', '1080111112808902656', '1080081111173306369', '1080491111114200192']
>>>
Also, never use dict or list for variable names, it shadows the built-in.
Maybe I'm misunderstanding you, let me know if is the case.
you have a dict of dicts, so first of all you need to get the first level (users) then you will have a a dict where the value is a list.
> some = {"user": {"tw_id": [["1080231111188251398"], ["1080111112808902656"], [], ["1080081111173306369"], [], ["1080491111114200192"]]}}
> some["user"]
{'tw_id': [['1080231111188251398'], ['1080111112808902656'], [], ['1080081111173306369'], [], ['1080491111114200192']]}
> some["user"]["tw_id"]
[['1080231111188251398'], ['1080111112808902656'], [], ['1080081111173306369'], [], ['1080491111114200192']]

Categories