I have this sample dataset
{'data1':200, 'data2':500}
I want to iterate this data in a range of 25, such that each iteration would give me the previous value * (1+0.05) within the iteration.
In this case the output of range of 2 would look like this:
{'data1':[200,210], 'data2':[500, 525]}
Anyone has an idea of how to go about this?
You could use a dictionary comprehension like this:
R = 25
d = {'data1': 200, 'data2': 500}
e = {k: [v * 1.05 ** i for i in range(R)] for k, v in d.items()}
print(e)
Output:
{'data1': [200.0, 210.0, 220.5, 231.52500000000003, 243.10125000000005, 255.25631250000006, 268.01912812500007, 281.4200845312501, 295.4910887578126, 310.26564319570326, 325.7789253554884, 342.0678716232628, 359.171265204426, 377.12982846464735, 395.98631988787974, 415.78563588227377, 436.5749176763874, 458.40366356020684, 481.3238467382171, 505.3900390751281, 530.6595410288844, 557.1925180803287, 585.0521439843452, 614.3047511835624, 645.0199887427406], 'data2': [500.0, 525.0, 551.25, 578.8125000000001, 607.7531250000001, 638.1407812500001, 670.0478203125002, 703.5502113281252, 738.7277218945316, 775.6641079892581, 814.447313388721, 855.1696790581572, 897.9281630110651, 942.8245711616183, 989.9657997196994, 1039.4640897056843, 1091.4372941909685, 1146.009158900517, 1203.309616845543, 1263.4750976878202, 1326.6488525722111, 1392.9812952008217, 1462.630359960863, 1535.761877958906, 1612.5499718568515]}
your can create a recursive function and a dictionnary comprehension which is faster than a loop:
d = {'data1':200, 'data2':500}
def g(value, n_range, factor):
if n_range <= 1:
return [value]
else:
return [value] + g(value * factor, n_range-1, factor)
def fct(data, n_range):
return {
k: g(v, n_range, factor=1.05)
for k, v in data.items()
}
fct(d, 2)
instead of g() you can also use a list comprehension such as:
def fct(data, n_range):
return {
k: [v*(1.05)**i for i in range(n_range)]
for k, v in data.items()
}
fct(d, 2)
dict = {'data1':200, 'data2':500}
e= {}
for key, value in dict.items():
v = value
tab = []
for i in range(25):
tab.append(v*(1.05)**i)
e[(key)]=tab
print(e)
OUTPUT :
{'data1': [200.0, 210.0, 220.5, 231.52500000000003, 243.10125000000005, 255.25631250000006, 268.01912812500007, 281.4200845312501, 295.4910887578126, 310.26564319570326, 325.7789253554884, 342.0678716232628, 359.171265204426, 377.12982846464735, 395.98631988787974, 415.78563588227377, 436.5749176763874, 458.40366356020684, 481.3238467382171, 505.3900390751281, 530.6595410288844, 557.1925180803287, 585.0521439843452, 614.3047511835624, 645.0199887427406], 'data2': [500.0, 525.0, 551.25, 578.8125000000001, 607.7531250000001, 638.1407812500001, 670.0478203125002, 703.5502113281252, 738.7277218945316, 775.6641079892581, 814.447313388721, 855.1696790581572, 897.9281630110651, 942.8245711616183, 989.9657997196994, 1039.4640897056843, 1091.4372941909685, 1146.009158900517, 1203.309616845543, 1263.4750976878202, 1326.6488525722111, 1392.9812952008217, 1462.630359960863, 1535.761877958906, 1612.5499718568515]}
Related
This is the input:
d={"mango":50,"apple":100,"banana":70} # this is the input
This should be the output:
{"mango":35,"apple":70,"banana":49}
I tried this:
f = {i:int(i*0.7) for i in d}
How do I do this using dictionary compression only?
Try this
f = { k: int(v * 0.7) for k, v in d.items() }
I have two dictionaries K and L. K is a Dictionary of lists and L is a nested dictionary
K={
'k1':[1,3,2],
'k2':[3,4,5],
'k3':[9,10,11]
}
L = {
'l1':{'a':'1','b':'1','c':'2'},
'l2':{'a':'1','b':'3','c':'2'},
'l3':{'a':'1','b':'2','c':'2'},
'l4':{'a':'1','b':'4','c':'2'}
}
What I need:
I want to create a new dictionary of lists based on the below condition.
I need to check if b values of L are present in the K dictionary of the list or not.
If present I need to return a new dictionary with Key of K
dictionary and Key of L dictionary.
For the above example, I need to return something like this
M = {'k1':[l1,l3,l2]
'k2':[l2,l4]
}
Here is the code that I have tried:
M= {}
for k, v in K.items():
temp = []
for i in v:
if L[i]['b'] in K[k]:
temp.append(i)
M[k] = temp
print(M)
Here is your solution:
new_dict, M = dict(), dict()
for key, val in L.items():
new_dict[val['b']] = key
for key, val in K.items():
for x in val:
if str(x) in new_dict:
tmp = new_dict[str(x)]
lst = M[key] if key in M else list()
lst.append(tmp)
M[key] = lst
print(M)
For the following K, L:
K = {
'k1':[1,3,2],
'k2':[3,4,5],
'k3':[9,10,11]
}
L = {
'l1':{'a':'1','b':'1','c':'2'},
'l2':{'a':'1','b':'3','c':'2'},
'l3':{'a':'1','b':'2','c':'2'},
'l4':{'a':'1','b':'4','c':'2'}
}
Output M:
M = {
'k2': ['l2', 'l4'],
'k1': ['l1', 'l2', 'l3']
}
[ Considered b values of L has a unique value, if not then you have to store it as a list in the new_dict dictionary.]
You were looking up the wrong thing in L here L[I]. I would do this by creating a lookup intially from L, that way you don't have to loop through L for every key in K. From there you can go through K once, looking up the items from the lookup.
Using defaultdict also allows you to handle the case where L has b values that are the same
from collections import defaultdict
b_val_to_l = defaultdict(set)
for lkey, ldict in L.items():
# For each ldict, extract the 'b' value, convert to an int and add the
# l key to the set of l values for the corresponding b value
b_val_to_l[int(ldict['b'])].add(lkey)
print(b_val_to_l)
M = defaultdict(list)
for k, v in K.items():
for i in v:
# For each value in the k, get the set of corresponding l values
b_set = b_val_to_l.get(i, set())
# Add to the output dict
M[k].extend(list(b_set))
print(M)
Just do this:
Mtemp = { k: [l for l in L
if int(L[l]['b']) in K[k]
] for k in K }
# Mtemp can have None values, so let's remove them...
M = { k: l for k, l in Mtemp.items() if len(l) > 0 }
Output:
{'k1': ['l1', 'l2', 'l3'], 'k2': ['l2', 'l4']}
I have a dict like this and I want to find minimum value:
fault = {
'A': {
'X': {
10: 0.34,
12: 0.32,
15: 1.53,
...
43: 0.2314
},
'Y': {
10: 0.12, <--- Min
12: 0.32,
15: 0.3214,
...
43: 1.4
}
},
'B': {
'X': {...},
'Y': {...}
},
'C': {
'X': {...},
'Y': {...}
},
'D': {
'A': {...},
'T': {...}
},
...
'Z': {...}
}
How can I find minimum value of inner dict with keys?
Expected output is something like that:
('A', ('Y', {10: 0.12}))
or
['A', 'Y', 10, 0.12]
It doesn't matter which data type output is as long as it gives the desired
Note: Nested dicts have same length
You can use recursion:
def d_min(d, c = []):
if all(not isinstance(i, dict) for i in d.values()):
_m = min(d.values())
yield (c, {a:b for a, b in d.items() if b == _m}, _m)
else:
yield from [i for a, b in d.items() for i in d_min(b, c+[a])]
def to_tuple(d, v):
return (d[0], v if not d[1:] else to_tuple(d[1:], v))
p, result, _ = min(d_min(fault), key=lambda x:x[-1])
print(to_tuple(p, result))
Output:
('A', ('Y', {10: 0.12}))
you can use a generator expresion with the built-in function min:
min(((i, (k0, (k1, {k2: i}) ))
for k0, d in fault.items()
for k1, v in d.items()
for k2, i in v.items()), key=lambda x: x[0])[1]
output:
('A', ('Y', {10: 0.12}))
if you hav
You can nest the min function with list iterators:
min([min([min(dd.values()) for dd in d.values()]) for d in fault.values()])
Not a general solution for arbitrary depths.
General recursive solution:
array = {
'A': {
'X': {
10: 0.34,
12: 0.32,
15: 1.53,
43: 0.2314,
},
'Y': {
10: 0.12,
12: 0.32,
15: 0.3214,
43: 1.4
}
},
}
def find_min(elem):
current_min = None
if isinstance(elem, dict):
for key, values in elem.items():
m = find_min(values)
if not current_min or m < current_min:
current_min = m
elif isinstance(elem, list):
for e in elem:
m = find_min(values)
if not current_min or m < current_min:
current_min = m
else:
current_min = elem
return current_min
print(find_min(array))
You would have to flatten the dictionary structure while retaining the hierarchy of keys corresponding to each value. Then use the min function on the flattened list and build your nested tuple/dict result from that.
K1,K2,K3,V3 = min( (K1,K2,K3,V3) for K1,V1 in fault.items() for K2,V2 in V1 for K3,V3 in V2),key=lambda r:r[-1])
result = (K1,(K2,{K3:V3}))
If the number of levels can vary, you will need to create use a recursive function to flatten the dictionary.
def flatDict(D):
for K,V in D.items():
if isinstance(V,dict):
for KVn in flatDict(V):
yield (K,)+KVn
else:
yield (K,V)
*keys,lastKey,value = min(flatDict(fault),key=lambda r:r[-1])
result = {lastKey:value}
for key in reversed(keys):
result = (key,result)
note, your resulting structure of nested tuples is going to be quite challenging to use if the number of levels changes. You might want to consider a simple tuple as returned by flatDict()
You can use a generator expression that iterates through the 3 levels of the dict structure and outputs the innermost items in the expected format, and pass it to the min function with a key function that returns the value of the innermost dict:
min(((k, (s, {i: v})) for k, d in fault.items() for s, m in d.items()
for i, v in m.items()), key=lambda t: next(iter(t[1][1].values())))
I have a dictionary contains lists of values and a list:
dict={'first':45, 'second':30, 'third':56}
list= [30,45]
I want to compare the value in the dictionary with the list and a match to add to a new dictionary after that, remove from the old dict all the values that are in the new dict: I'm doing something like this:
def get_sessions(self, talks):
result_sessions = {}
for k, v in self.sessions.items():
for i in talks:
if v == i:
result_sessions[k] = v
for k, v in result_sessions.items():
del self.sessions[k]
return result_sessions
Maybe you know a more elegant solution? any help?
This is one approach.
Ex:
d ={'first':45, 'second':30, 'third':56}
lst = [30,45]
result_sessions = {k: v for k, v in d.items() if v in lst}
d = { k : d[k] for k in set(d) - set(result_sessions) }
print(result_sessions)
print(d)
Output:
{'second': 30, 'first': 45}
{'third': 56}
d1 = {'weight':1, 'data': { 'apples': 8, 'oranges': 7 } }
d2 = {'weight':3, 'data': { 'apples': 4, 'bananas': 3 } }
all_dictionaries = [d1, d2, ... ]
def mergeDictionariesWithWeight(all_dictionaries)
How do I merge these dictionaries together (if overlap, multiple value with the weight)
The function would return:
{ 'apples': 4, 'oranges': 7, 'bananas': 3 }
Apples is 4 because 8 * .25 + 4 * .75
Edit: I just wrote one that takes the average, something like this. But of course it's really different from what I want to do, because I stick everything in a list and just divide by the length.
result = {}
keymap = {}
for the_dict in dlist:
for (k, v) in the_dict.items():
if not keymap.has_key(k):
keymap[k] = []
keymap[k].append(v)
for (k, v) in keymap.items():
average = sum(int(x) for x in keymap[k]) / float(len(keymap[k]))
result[k] = float(average)
return result
>>> from collections import defaultdict
>>> d=defaultdict(lambda:(0,0))
>>> for D in all_dictionaries:
... weight = D['weight']
... for k,v in D['data'].items():
... d[k]=d[k][0]+weight*v,d[k][1]+weight
...
>>> dict((k,v[0]/v[1]) for k,v in d.items())
{'apples': 5, 'oranges': 7, 'bananas': 3}
If you need floating point result
>>> dict((k,1.*v[0]/v[1]) for k,v in d.items())
{'apples': 5.0, 'oranges': 7.0, 'bananas': 3.0}
Notes about defaultdict
Often you see defaultdict(int) or defaultdict(list) maybe even defaultdict(set). The argument to defaultdict must be callable with no parameters. The result of calling this parameter is used whenever a key is found to be missing. ie - calling this returns the default value for the dictionary
for example
>>> d=defaultdict(int)
>>> d[1]
0
>>> d['foo']
0
This is often used for counting things up because int() returns 0. If you want the default value to be 1 instead of 0, it's more tricky because you can't pass a parameter to int, but all you need is a callable that returns 1. This can be accomplished without too much fuss by using a lambda function.
>>> d=defaultdict(lambda:1)
>>> d[1]
1
>>> d['foo']
1
In this answer, I want to keep track of the weighted total, and the total of the weights. I can do this by using a 2-tuple as the default value.
>>> d=defaultdict(lambda:(0,0))
>>> d[1]
(0, 0)
>>> d['foo']
(0, 0)
Here's a solution that first uses gathers the items into a list using a temporary dict, and then computes the final weighted dict. It can probably be done without a temporary, but this is easy to understand.
from collections import defaultdict
def mergeDictionariesWithWeight(dlist):
tmp = defaultdict(list)
for d in dlist:
weight = d['weight']
for k, v in d['data'].items():
tmp[k].append((weight, v))
r = {}
for k, v in tmp.items():
# If there's just one item, ignore the weight
if len(v) == 1:
r[k] = v[0][1]
else:
total_weight = sum((x[0] for x in v), 0.0)
r[k] = sum(x[1] * x[0]/total_weight for x in v)
return r
Returns: {'apples': 5.0, 'oranges': 7, 'bananas': 3} (because 8 * .25 + 4 * .75 = 5.0)
try this:
def mergeDictionariesWithWeight(all_dictionaries):
weightSum = 0
weightDictionary ={}
for dictionary in all_dictionaries:
weight = dictionary['weight']
data = dictionary['data']
#find the total weight of the elements in data
for (k,v) in data.items():
if k in weightDictionary:
weightDictionary[k] += weight*v
weightSum += weight
#normalize the results by deviding by the weight sum
for (key, value) in weightDictionary:
weightDictionary[key] = value / float(weightSum)
return weightDictionary
d1 = {'weight':1, 'data': { 'apples': 8, 'oranges': 7 } }
d2 = {'weight':3, 'data': { 'apples': 4, 'bananas': 3 } }
all_dictionaries = [d1, d2]
mergeDictionariesWithWeight(all_dictionaries)
from collections import defaultdict
def merge_dictionaries_with_weight(all_dictionaries):
totals = defaultdict(int)
result = defaultdict(int)
for each in all_dictionaries:
weight = float(each['weight'])
for key, value in each['data'].items():
totals[key] += weight
result[key] += weight * value
for key, total in totals.items():
result[key] /= total
return result
Algorithmically indistinguishable from gnibbler's, but somehow the generator expression pleases me.
>>> from collections import defaultdict
>>> weights, values = defaultdict(int), defaultdict(int)
>>> key_weight_value = ((key, d['weight'], value)
for d in all_dictionaries
for key, value in d['data'].iteritems())
>>> for k, w, v in key_weight_value:
... weights[k], values[k] = weights[k] + w, values[k] + w * v
...
>>> dict((k, values[k] * 1.0 / weights[k]) for k in weights)
{'apples': 5.0, 'oranges': 7.0, 'bananas': 3.0}