Populate a dictionary with for loop - python

I'd like to create a dictionary that would look like this:
{'area1': ['x1_area1', 'x2_area1'], 'area2': ['x1_area2', 'x2_area2']}
I'm trying to use a for loop:
dict_ ={}
keys =["area1","area2"]
for key in keys :
dict_ = {key : ["x1_"+ key,"x2_"+ key]}
dict_.update(dict_)
But I get this output:
{'area2': ['x1_area2', 'x2_area2']}

Try it:
keys =["area1","area2"]
dict_ = {}
for key in keys :
dict_[key] = ["x1_"+ key,"x2_"+ key]
dict_

Try this
res = {k: [f'{x}_{k}' for x in ('x1', 'x2')] for k in keys}
print(res)
Output:
{'area1': ['x1_area1', 'x2_area1'], 'area2': ['x1_area2', 'x2_area2']}

Inside your loop, you’re redefining dict_ and thus overwriting the existing values. Use a different variable name, or just inline its usage entirely:
dict_ = {}
keys = ["area1", "area2"]
for key in keys:
dict_.update({key : ["x1_" + key, "x2_" + key]})
This is taking over 100% of your code and just fixing the specific issues. There are better, more “Pythonic” solutions for this problem, which are explained in other answers.

The original code overrides the first value.
The following code will update without override:
keys =["area1","area2"]
dict_ = {}
for key in keys :
x = {key : ["x1_"+ key,"x2_"+ key]}
dict_.update(x)
# {'area1': ['x1_area1', 'x2_area1'], 'area2': ['x1_area2', 'x2_area2']}
print(dict_)

When looking at how to add items to a dictionaries, it seems like dict_[key] = "answer"
is the way to go.
dict_ = {}
keys = ["area1", "area2"]
for key in keys:
dict_[key] = ["x1_" + key, "x2_" + key]
print(dict_)
https://www.w3schools.com/python/python_dictionaries.asp

Related

how to change tuple key into multilevel dict

I have a dictionary that looks like this:
d = {key1 : {(key2,key3) : value}, ...}
so it is a dictionary of dictionaries and in the inside dict the keys are tuples.
I would like to get a triple nested dict:
{key1 : {key2 : {key3 : value}, ...}
I know how to do it with 2 loops and a condition:
new_d = {}
for key1, inside_dict in d.items():
new_d[key1] = {}
for (key2,key3), value in inside_dict.items():
if key2 in new_d[key1].keys():
new_d[key1][key2][key3] = value
else:
new_d[key1][key2] = {key3 : value}
Edit: key2 values are not guaranteed to be unique. This is why I added the condition
It feels very unpythonic to me.
Is there a faster and/or shorter way to do this?
You could use the common trick for nesting dicts arbitrarily, using collections.defaultdict:
from collections import defaultdict
tree = lambda: defaultdict(tree)
new_d = tree()
for k1, dct in d.items():
for (k2, k3), val in dct.items():
new_d[k1][k2][k3] = val
If I understand the problem correctly, for this case you can wrap all the looping up in a dict comprehension. This assumes that your data is unique:
data = {"key1": {("key2", "key3"): "val"}}
{k: {keys[0]: {keys[1]: val}} for k,v in data.items() for keys, val in v.items()}

Adding a key to a dictionary where the values are lists In Python

I want to add the variable key to the dictionary as a key, as well as add a value to a list. Is this the right way of going about this?
dict = {}
key = 'hold'
value = 'holdtwo'
value_two = 'holdthree'
dict[key].append(value)
dict[key].append(value_two)
You can use dedfaultdict to achieve this
from collections import defaultdict
dictionary = defaultdict(list)
key = 'hold'
value = 'holdtwo'
value_two = 'holdthree'
dictionary[key].append(value)
dictionary[key].append(value_two)
Don't use use keywords as variables!
dict = {} # dict is a keyword
Your asking for problems with it!
dict1 = {}
dict1['key'] = ['hold','hold2','hold3']
dict1['key'].append('hold4')
or a more extensive and larger variation on holding stuff (example):
dict1 = {}
keys = ['key1', 'key2', 'key3']
for key1 in keys:
dict1[key1] = []
vals = [1,2,3,4,5,6,7,8,9,10] #Just some values to store in the dicts
iKey = 1 #iKey is just an offset to show the differences between keys
for key2 in dict1:
iKey = iKey + 5
for val in vals:
dict[key2].append(iKey*val)
Loads of options.
Solved!
If I want to put in a new key that has an empty list, I use:
new_key = 'something'
dict[new_key] = []
If I want to add a value to an existing key's list:
value = 'something else'
dict[new_key].append(value)
This seems to work just fine with variables as keys.

inversing a dictionary in python with duplicate values

I need to inverse a dictionary so that each old value will now be a key and the old keys will be the new values.
The trick is that there could be multiple values that are the same in the old dictionary so I need each value in the new dictionary to be a list, and if there were identical values in the old dictionary then they both will be in the list of the value of the new dictionary.
for example:
the dictionary {"python" : 1, "is" : 1, "cool" : 2}
would end up as: {1 : ["python", "is"], 2 : ["cool"]}
this is what I tried:
def inverse_dict(my_dict):
new_dict = {}
values_list = list(my_dict.values())
new_dict = new_dict.fromkeys(values_list)
for key in new_dict:
new_dict[key] = []
for old_key in my_dict:
new_dict[my_dict[old_key]] = list(new_dict[my_dict[old_key]]).append(old_key)
return new_dict
Would greatly appreciate any help with my approach (and better approaches to the problem) as I am very new to Python, thanks!
You can use dict.setdefault check if a key exists in the dictionary and if not, create new value (in this case empty list []):
d = {"python" : 1, "is" : 1, "cool" : 2}
reversed_d = {}
for k, v in d.items():
reversed_d.setdefault(v, []).append(k)
print(reversed_d)
Prints:
{1: ['python', 'is'], 2: ['cool']}
This can be more explicitly rewritten as:
d = {"python" : 1, "is" : 1, "cool" : 2}
reversed_d = {}
for k, v in d.items():
if v not in reversed_d:
reversed_d[v] = [k]
else:
reversed_d[v].append(k)
print(reversed_d)
You can use a defaultdict to avoid the pre-fill step
from collections import defaultdict
def inverse_dict(my_dict: dict):
new_dict = defaultdict(list)
for k, v in my_dict.items():
new_dict[v].append(k)
return new_dict
Though I prefer #azro's answer with the default dict, another solution is doing it with dictionary and list comprehensions.
It looks like this:
{value : [key for key in my_dict if my_dict[key] == value] for value in set(my_dict.values())}
What it does is runs over the values of the dictionary without duplicates - set(my_dict.values()).
It builds every value as a key (because it's on the left side of the ":").
And its value is a list of the keys that point to that value - [key for key in my_dict if my_dict[key] == value].

Is there a better way of re-arranging dictionary values?

I have the following dictionary:
files = {
'Input.txt': 'Randy',
'Code.py': 'Stan',
'Output.txt': 'Randy'}
I would like to return a dictionary where the keys are the names and where the corresponding value is a list of the filename:
{'Randy': ['Input.txt', 'output.txt'], 'Stan': ['Code.py']}
I managed to do it with 2 for loops:
def group_by_owners(files):
my_dict = {}
for value in files.values():
if value not in my_dict:
my_dict[value] = []
for key, value in files.items():
if value in my_dict.keys():
my_dict[value].append(key)
return my_dict
Is there a more efficient / elegant way of doing this?
Thanks
Option 1: defaultdict
Default dictionary with a default value of an empty list, so you append values to it.
This solution is preferable.
files = {
'Input.txt': 'Randy',
'Code.py': 'Stan',
'Output.txt': 'Randy'}
from collections import defaultdict
inv_map = defaultdict(list)
{inv_map[v].append(k) for k, v in files.items()}
# {'Randy': ['Input.txt', 'Output.txt'], 'Stan': ['Code.py']}
print(inv_map)
Option 2: Dictionary
files = {
'Input.txt': 'Randy',
'Code.py': 'Stan',
'Output.txt': 'Randy'}
inv_map = {}
for k, v in files.items():
inv_map[v] = inv_map.get(v, []) + [k]
# {'Randy': ['Input.txt', 'Output.txt'], 'Stan': ['Code.py']}
print(inv_map)
Here is my take on this. Using defaultdict to avoid creating the initial list, and just use append
from collections import defaultdict
def group_by_owners(files):
# Creates a dictionary that it's initial value is a list
# therefore you can just start using `append`
result = defaultdict(list)
for key, value in files.items():
result[value].append(key)
return result

Python: How to combine two dictionaries in python such that the resultant contains key as the value from the first

I have two dictionaries as follows:
mydictionary_1 = {1:'apple',2:'banana'}
mydictionary_2 = {1:50,2:30}
The resultant dictionary should be such that it takes the key as the value of first dictionary.
Result_dictionary= {'apple':50, 'banana':30}
You can use a dictionary comprehension using the values of the first dictionary as the keys of the resulting dictionary. This assumes all keys of the first are present in the second dict
{v: dict2[k] for k, v in dict1.items()}
you can also add a check for the presence of the keys in the second dictionary
{v: dictionary_2[k] for k, v in dictionary_1.items() if k in dictionary_2}
Loop through one of the dictionaries and check if the value for a key in mydictionary_1 exists in mydictionary_2.
You can achieve this using python's dictionary comprehension -
Result_dictionary = { v:mydictionary_2[k] for k,v in mydictionary_1.iteritems() if k in mydictionary_2.keys()}
To see how this list comprehension is working you can even use general for loop to loop through each key, value pair in mydictionary_1
for key,value in mydictionary_1.iteritems():
if key in mydictionary_2.keys():
Result_dictionary[value]=mydictionary_2[key]
Dictionary comprehension is an ideal solution for this one, as previously mentioned. Here is a for loop example:
def combine_dictionaries(dict1, dict2):
result_dictionary = {}
for key in dict1.keys():
result_dictionary[dict1[key]] = dict2[key]
return result_dictionary
combine_dictionaries({1:'apple', 2:'banana'}, {1:50, 2:30})
>>>{'apple': 50, 'banana': 30}
This assumes all values of the dict1 are present in the dict2.
def dict_cross_match(dict1, dict2):
new_dict = {}
for item in dict1.keys():
if item in dict2.keys():
new_dict[dict1[item]] = dict2[item]
return new_dict
mydictionary_1 = {1:'apple',2:'banana'}
mydictionary_2 = {1:50,2:30}
print(dict_cross_match(mydictionary_1, mydictionary_2))

Categories