how to multiply dictionary values which are multiples - python

How do I multiply the values of this dictionary by 2?
d = {'a': (1,2), 'y': (2,4), 'z': (10,3)}
I get this
for i in d:
print(d[i]*2)
[1, 2, 1, 2]
[2, 4, 2, 4]
[10, 3, 10, 3]
but I want to achieve:
[2,4]
[4,8]
[20,6]

You're attempting to multiply a tuple which is resulting in the duplication of the values in your tuple. Instead, to algebraically interact with your tuples, you must do so one value at a time.
for i in d:
print(d[i][0]*2, d[i][1]*2)

You need to iterate through dictionary values and multiply each element by 2, not tuples * 2:
d = {'a': (1,2), 'y': (2,4), 'z': (10,3)}
for x in d.values():
print([y*2 for y in x])
# [2, 4]
# [4, 8]
# [20, 6]
What you are doing is:
>>> tupl = (1, 2)
>>> tupl * 2
(1, 2, 1, 2)

Here you need to do list comprehension
d = {'a': (1,2), 'y': (2,4), 'z': (10,3)}
for k in d.keys():
d[k] = [2*x for x in d[k]]
print(d)
{'a': [2, 4], 'y': [4, 8], 'z': [20, 6]}

Related

From nested for loop to dictionary comprehension?

I have a dictionary (dict_) with lists of integers as values.
I want to make an operation on these list and save the result as a new dictionary.
Below I do an operation on these list, adding 2 if the elements are larger than 5. I use a nested for loop to achieve this. How would I achieve the same using dictionary comprehension?
dict_={'a':[5, 8, 7],
'b':[4, 7, 2],
'c':[2, 2, 4]}
print(dict_)
#Output: {'a': [5, 8, 7], 'b': [4, 7, 2], 'c': [2, 2, 4]}
dict_new = {}
for k, v in dict_.items():
list_temp=[]
for e in v:
if e > 5:
ne=e + 2
list_temp.append(ne)
else:
list_temp.append(e)
dict_new[k] = list_temp
print(dict_new)
# Output: {'a': [5, 8, 7], 'b': [4, 7, 2], 'c': [2, 2, 4]}
this could be your dict-comprehension:
{k: [i if i <= 5 else i + 2 for item in v] for k, v in dict_.items()}
note that you need a list-comprehension for the values as well.
noting that False is basically 0 and True is 1 you could simplify (but maybe making it more obscure?) the list-comprehension:
{k: [i + 2 * (i > 5) for i in v] for k, v in dict_.items()}
You can do this, but as you are working with both dicts and lists, you will want to use a list comprehension also.
my_dict ={'a':[5, 8, 7],
'b':[4, 7, 2],
'c':[2, 2, 4]}
d = {key: [x if x <= 5 else x + 2 for x in value] for key, value in my_dict.items()}
This should solve the above problem and return:
{'a': [5, 10, 9], 'b': [4, 9, 2], 'c': [2, 2, 4]}
for k, v in dict_.items():
dict_new[k] = [e + 2 if e > 5 else e for e in v ]

Restructuring the hierarchy of dictionaries in Python?

If I have a nested dictionary in Python, is there any way to restructure it based on keys?
I'm bad at explaining, so I'll give a little example.
d = {'A':{'a':[1,2,3],'b':[3,4,5],'c':[6,7,8]},
'B':{'a':[7,8,9],'b':[4,3,2],'d':[0,0,0]}}
Re-organize like this
newd = {'a':{'A':[1,2,3],'B':[7,8,9]},
'b':{'A':[3,4,5],'B':[4,3,2]},
'c':{'A':[6,7,8]},
'd':{'B':[0,0,0]}}
Given some function with inputs like
def mysteryfunc(olddict,newkeyorder):
????
mysteryfunc(d,[1,0])
Where the [1,0] list passed means to put the dictionaries 2nd level of keys in the first level and the first level in the 2nd level. Obviously the values need to be associated with their unique key values.
Edit:
Looking for an answer that covers the general case, with arbitrary unknown nested dictionary depth.
Input:
d = {'A':{'a':[1,2,3],'b':[3,4,5],'c':[6,7,8]},
'B':{'a':[7,8,9],'b':[4,3,2],'d':[0,0,0]}}
inner_dict={}
for k,v in d.items():
print(k)
for ka,va in v.items():
val_list=[]
if ka not in inner_dict:
val_dict={}
val_dict[k]=va
inner_dict[ka]=val_dict
else:
val_dict=inner_dict[ka]
val_dict[k]=va
inner_dict[ka]=val_dict
Output:
{'a': {'A': [1, 2, 3], 'B': [7, 8, 9]},
'b': {'A': [3, 4, 5], 'B': [4, 3, 2]},
'c': {'A': [6, 7, 8]},
'd': {'B': [0, 0, 0]}}
you can use 2 for loops, one to iterate over each key, value pair and the second for loop to iterate over the nested dict, at each step form the second for loop iteration you can build your desired output:
from collections import defaultdict
new_dict = defaultdict(dict)
for k0, v0 in d.items():
for k1, v1 in v0.items():
new_dict[k1][k0] = v1
print(dict(new_dict))
output:
{'a': {'A': [1, 2, 3], 'B': [7, 8, 9]},
'b': {'A': [3, 4, 5], 'B': [4, 3, 2]},
'c': {'A': [6, 7, 8]},
'd': {'B': [0, 0, 0]}}
You can use recursion with a generator to handle input of arbitrary depth:
def paths(d, c = []):
for a, b in d.items():
yield from ([((c+[a])[::-1], b)] if not isinstance(b, dict) else paths(b, c+[a]))
from collections import defaultdict
def group(d):
_d = defaultdict(list)
for [a, *b], c in d:
_d[a].append([b, c])
return {a:b[-1][-1] if not b[0][0] else group(b) for a, b in _d.items()}
print(group(list(paths(d))))
Output:
{'a': {'A': [1, 2, 3], 'B': [7, 8, 9]}, 'b': {'A': [3, 4, 5], 'B': [4, 3, 2]}, 'c': {'A': [6, 7, 8]}, 'd': {'B': [0, 0, 0]}}

Convert list of lists to list of dictionaries based on order of items in sublist

I would like to convert my list of lists to list of dictionaries. Values of first list should be my keys and remaining all should be treated as values.
For example:
[['a','b','c'],[1,2,3],[4,5,6],[7,8,9]]
should convert to
[{'a':[1,4,7]}, {'b': [2,5,8]},{'b': [3,6,9]}]
I found this but it did n't help for me..
Any help would be greatly appreciated. Thanks
Use zip to transpose your array into [('a', 1, 4, 7), ...]; pop off the first element as key, listify the rest as value.
arr = [['a','b','c'],[1,2,3],[4,5,6],[7,8,9]]
[{ e[0]: list(e[1:])} for e in zip(*arr)]
# => [{'a': [1, 4, 7]}, {'b': [2, 5, 8]}, {'c': [3, 6, 9]}]
Using a list comprehension with sequence unpacking:
L = [['a','b','c'],[1,2,3],[4,5,6],[7,8,9]]
res = [{names: nums} for names, *nums in zip(*L)]
print(res)
[{'a': [1, 4, 7]}, {'b': [2, 5, 8]}, {'c': [3, 6, 9]}]
a=[['a','b','c'],[1,2,3],[4,5,6],[7,8,9]]
dictionary_values=[dict([(a[0][i],list(zip(*a[1:])[i])) for i in range (len(a)-1)])]
output:
[{'a': [1, 4, 7], 'b': [2, 5, 8], 'c': [3, 6, 9]}]

How to create a function (Iteration/Recursion) to run over a dictionary of tuples in Python?

I have a Python dictionary of lists like this one:
d = {'A': [(4, 4, 3), [1, 2, 3, 4, 5]],
'B': [(2, 1, 2), [5, 4, 3, 2, 1]],
'C': [(4, 1, 1), [2, 4, 1, 2, 4]]}
I need to create a formula that accesses the elements of the dictionary and, for every value [t, l]:
Calculates the mean of t (let's call this m);
Takes a random sample s, with replacement and of length len(t), from l;
Compares m with the mean of s - True if m is greater than the mean of s, False otherwise;
Repeats this process 10,000 times
Returns the percentage of times m is greater than the mean of s.
The output should look like:
In [16]: test(d)
Out[16]: {'A': 0.5, 'B': 0.9, 'C': 0.4}
I think I'm not that far from an answer, this is what I have tried:
def test(dict):
def mean_diff(dict):
for k, (v0, v1) in dict.iteritems():
m = np.mean(v0) > (np.mean(npr.choice(v1, size=(1, len(v0)), replace=True)))
return ({k: m})
for k, (v0, v1) in dict.iteritems():
bootstrap = np.array([means_diff(dict) for _ in range(10000)])
rank = float(np.sum(bootstrap))/10000
return ({k: rank})
However, I got:
RuntimeError: maximum recursion depth exceeded while calling a Python object
I'd use a list comprehension that essentially selects a random value and compares it to the mean. This will produce a list of True/False. If you take the mean of that, it will be averaging a list of 1's and 0's, so it will give you the aggregate probability.
import numpy as np
d = {'A': [(4, 4, 3), [1, 2, 3, 4, 5]],
'B': [(2, 1, 2), [5, 4, 3, 2, 1]],
'C': [(4, 1, 1), [2, 4, 1, 2, 4]]}
def makeRanks(d):
rankDict = {}
for key in d:
tup = d[key][0]
mean = np.mean(tup)
l = d[key][1]
rank = np.mean([mean > np.mean(np.random.choice(l,len(tup))) for _ in range(10000)])
rankDict[key] = rank
return rankDict
Testing
>>> makeRanks(d)
{'C': 0.15529999999999999, 'A': 0.72130000000000005, 'B': 0.031899999999999998}

simple dictionary manipulation in python

groups = ['A','B','C']
ranges = [1,2,3,4,5,6,7,8,9]
my_dict = {}
for g in groups:
my_dict[g] = ???
The result (my_dict) should be as follows:
{'A': array([1, 2, 3], dtype=int64), 'B': array([4,5,6], dtype=int64)), 'C': array([7,8,9], dtype=int64)}
First I would turn your ranges in to properly sized chunks:
>>> ranges = zip(*[iter(ranges)]*len(groups))
>>> print(ranges)
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
This will create chunks of len(groups) items which you can then feed to zip() in the second part.
Then create the dictionary, using a dictionary comprehension and zip().
>>> from numpy import array
>>> my_dict = {g: array(r) for g, r in zip(groups, ranges)}
>>> print(my_dict)
{'A': array([1, 2, 3]), 'C': array([7, 8, 9]), 'B': array([4, 5, 6])}
>>> import itertools
>>>
>>> groups = ['A','B','C']
>>> ranges = [1,2,3,4,5,6,7,8,9]
>>> dict(zip(groups,
... (list(itertools.islice(it, 3)) for it in [iter(ranges)]*3)))
{'A': [1, 2, 3], 'C': [7, 8, 9], 'B': [4, 5, 6]}

Categories

Resources