adding list of items into the values of Dictionary - python-3.x

Let's say i have a list [10,9,8,7]
and i have a my_dict {4:0, 3: 0, 2: 0 , 1 : 0}
I'm new to Python and I've tried researching how to go about this but I still could not find an answer. I want to add the list to the values of my_dict, how should I approach this?
my_list = [10,9,8,7]
my_dict = {4:0, 3: 0, 2: 0 , 1 : 0}

Is this what you're looking for
for index, (key,value) in enumerate(my_dict.items()):
my_dict[key] = my_list[index]
print(my_dict)

Related

Python: Convert 2d list to dictionary with indexes as values

I have a 2d list with arbitrary strings like this:
lst = [['a', 'xyz' , 'tps'], ['rtr' , 'xyz']]
I want to create a dictionary out of this:
{'a': 0, 'xyz': 1, 'tps': 2, 'rtr': 3}
How do I do this? This answer answers for 1D list for non-repeated values, but, I have a 2d list and values can repeat. Is there a generic way of doing this?
Maybe you could use two for-loops:
lst = [['a', 'xyz' , 'tps'], ['rtr' , 'xyz']]
d = {}
overall_idx = 0
for sub_lst in lst:
for word in sub_lst:
if word not in d:
d[word] = overall_idx
# Increment overall_idx below if you want to only increment if word is not previously seen
# overall_idx += 1
overall_idx += 1
print(d)
Output:
{'a': 0, 'xyz': 1, 'tps': 2, 'rtr': 3}
You could first convert the list of lists to a list using a 'double' list comprehension.
Next, get rid of all the duplicates using a dictionary comprehension, we could use set for that but would lose the order.
Finally use another dictionary comprehension to get the desired result.
lst = [['a', 'xyz' , 'tps'], ['rtr' , 'xyz']]
# flatten list of lists to a list
flat_list = [item for sublist in lst for item in sublist]
# remove duplicates
ordered_set = {x:0 for x in flat_list}.keys()
# create required output
the_dictionary = {v:i for i, v in enumerate(ordered_set)}
print(the_dictionary)
""" OUTPUT
{'a': 0, 'xyz': 1, 'tps': 2, 'rtr': 3}
"""
also, with collections and itertools:
import itertools
from collections import OrderedDict
lstdict={}
lst = [['a', 'xyz' , 'tps'], ['rtr' , 'xyz']]
lstkeys = list(OrderedDict(zip(itertools.chain(*lst), itertools.repeat(None))))
lstdict = {lstkeys[i]: i for i in range(0, len(lstkeys))}
lstdict
output:
{'a': 0, 'xyz': 1, 'tps': 2, 'rtr': 3}

Erroneous behaviour while updating nested dictionary python3

While working on defaultdict class of collection package in python3.7, I see that new key is generated from the duplicate of last key, instead of initiating dictionary. Is there a way to initiate new element with given dictionary which is init_dict in below example code.
Example code to reproduce error:
from collections import defaultdict
init_dict = {'buy_qty': 0,
'sell_qty': 0}
pnl = defaultdict(lambda: init_dict)
pnl['a']['buy_qty'] += 1
pnl['a']['sell_qty'] += 1
Now when I do
pnl['b']
gives me
{'buy_qty': 1, 'sell_qty': 1}
I am looking for pnl['b'] to be initialized with init_dict. How can I achieve that?
Your copying by reference, not by value. So whatever you do to one dictionary, the other will be affected.
You can check this with the id() function:
print(id(pnl['a']))
print(id(pnl['b']))
print(id(pnl['a']) == id(pnl['b']))
Which will give the same memory addresses:
1817103232768
1817103232768
True
verifying that they are the same objects. You can fix this by assigning a shallow copy of the dictionary using dict.copy(), as mentioned in the comments:
pnl = defaultdict(lambda: init_dict.copy())
Or casting dict():
pnl = defaultdict(lambda: dict(init_dict))
Or using ** from PEP 448 -- Additional Unpacking Generalizations
:
pnl = defaultdict(lambda: {**init_dict})
Additionally, consider using a collections.Counter to do the counting, instead of initializing zero count dictionaries yourself:
from collections import defaultdict, Counter
pnl = defaultdict(Counter)
pnl['a']['buy_qty'] += 1
pnl['a']['sell_qty'] += 1
print(pnl)
# defaultdict(<class 'collections.Counter'>, {'a': Counter({'buy_qty': 1, 'sell_qty': 1})})
print(pnl['b']['buy_qty'])
# 0
print(pnl['b']['buy_qty'])
# 0
pnl['b']['buy_qty'] += 1
pnl['b']['sell_qty'] += 1
print(pnl)
# defaultdict(<class 'collections.Counter'>, {'a': Counter({'buy_qty': 1, 'sell_qty': 1}), 'b': Counter({'buy_qty': 1, 'sell_qty': 1})})
Counter is a subclass of dict, so they will work the same as normal dictionaries.

Find maximum value in a nested dictionary

I am having trouble understanding how to pull the maximum value of a nested dictionary when it is structured as so:
dict = {'City': {1: {'avg_dur': 10.58568297387339,
'n_trips': 1901,
'tot_dur': 20123.383333333313},
2: {'avg_dur': 12.25947507658035,
'n_trips': 2394,
'tot_dur': 29349.183333333356},
3: {'avg_dur': 12.95495652953303,
'n_trips': 3719,
'tot_dur': 48179.48333333334}}}
I am trying to extract the key for the maximum 'avg_trips' function. In the snippet above, I would expect the answer to return 3. I think I need to use lambda here, but I'm not sure how that works with nested dictionaries to this level.
Use max with key
Ex:
dict = {'City': {1: {'avg_dur': 10.58568297387339,
'n_trips': 1901,
'tot_dur': 20123.383333333313},
2: {'avg_dur': 12.25947507658035,
'n_trips': 2394,
'tot_dur': 29349.183333333356},
3: {'avg_dur': 12.95495652953303,
'n_trips': 3719,
'tot_dur': 48179.48333333334}}}
print(max(dict["City"].items(), key=lambda x: x[1]['n_trips'])[0])
Output:
3
You could also sort the keys by n_trips and take the last one:
>>> sorted(mydict['City'].keys(), key=lambda x: mydict['City'][x]['n_trips'])[-1]
3

Python - Insert value to list in a dictionary

I need your help to fix my code. I try to append a value to a list in a dictionary.
def distance(x1, y1, x2, y2):
dis=((x1-x2)**2) + ((y1-y2)**2)
return dis
def cluster_member_formation2(arrCH, arrN, k):
dicCH = dict.fromkeys(arrCH,[])
arrE = []
for j in range(len(arrCH)):
d_nya = distance(arrN[1][0], arrN[1][1], arrN[arrCH[j]][0], arrN[arrCH[j]][1])
arrE.append(d_nya)
minC = min(arrE)
ind = arrE.index(minC)
x = arrCH[ind]
dicCH[x].append(1)
print(arrE, minC, ind, x, dicCH)
arrCH=[23, 35]
arrN={0:[23, 45, 2, 0], 1:[30,21,2,0], 23:[12, 16, 2, 0], 35:[48, 77, 2, 0]}
cluster_member_formation2(arrCH, arrN, 1)
The output:
[349, 3460] 349 0 23 {35: [1], 23: [1]}
I try to calculate the distance between node 1 and all node in arrCH, and then take the minimum distance. In the output show the result of arrE is [349, 3460], so the minimum is 349. 349 has index 0, then I find arrCH with index 0, likes arrCH[0]=23. Finally, I want update dicCH[23].append(1) so the result is
{35: [], 23: [1]}
But, why my code update the all keys, 35 and 23?
I hope someone can help me.
Thank you..
classmethod fromkeys(seq[, value])
Create a new dictionary with keys
from seq and values set to value.
All of your dictionary values reference the same single list instance ([]) which you provide as a value to the fromkeys function.
You could use dictionary comprehension as seen in this answer.
dicCH = {key: [] for key in arrCH}

finding the keys of all the largest values in python dictionary?

if I have a dictionary
x ={0: 0, 1: 4, 2: 0, 3: 2, 4: 2, 5: 4}
how do i get the keys of all the largest values
In this case they would be 1 and 5 .
Not a duplicate question. looking to find all the keys and not just the one.
x ={0: 0, 1: 4, 2: 0, 3: 2, 4: 2, 5: 4}
maximum = max(x.values())
keys = [key for key, value in x.items() if value == maximum]
print(keys) # => [1, 5]
There is a class in collections called Counter that does exactly what you want. It provides the exact functionality you require via it's most_common method:
from collections import counter
maxes = Counter(x).most_common(2)
print([x[0] for x in maxes])
[1, 5]
Now this is probably not exactly what you want because I hard coded in the number 2. You can get this by using another Counter on the values of your dictionary!
x = Counter(x) # This preserves x: just makes it a subclass of dict
max_count = Counter(x.values())[x.most_common(1)[0][1]]
maxes = x.most_common(max_count)
maxes = [x[0] for x in maxes]
Here, I compute the number of times that the most common value occurs by counting all the different values, and then checking the maximum one using x.most_common(1)[0][1].
Please do not select this answer. #BrightOne has the right answer. This is just a thing I did to see if I could avoid using anything but Counters. It is not actually a good idea.

Resources