My input is a list and I want to convert it into a dictionary and add all values for the same keys. like in the give example in a random list k has two values 1 and 3 so value of k in dictionary will be {'k':4,'D':2}. And then sort it in alphabetic order
Input: ['k:1','D:2','k:3']
Output {'k':4,'D':2}
dlist = ['k:1','D:2','k:3']
dick ={}
for x in dlist:
key,value = x.split(':')
dick[key] = int(value)
print(dick)
I have the above code but I don't know how to add two values for k?
You need to actually add the value to the pre-existing value. In your code now you just overwrite the old value with the new one.
dick = {}
for x in dlist:
key, value = x.split(':')
dick[key] = dick.get(key, 0) + int(value)
dict.get(key, 0) gets the value of the key in the dictionary, with a default of zero
This is possible by making dick a defaultdict. So, now you can just += the value.
from collections import defaultdict
dlist = ['k:1','D:2','k:3']
dick = defaultdict(int)
for x in dlist:
key, value = x.split(':')
dick[key] += int(value)
print(dick)
You can use groupby from itertools to group same values and then sum.
import itertools
a=['k:1','D:2','k:3']
print({k:sum([int(j[1]) for j in v]) for k,v in itertools.groupby([i.split(":") for i in sorted(a)], lambda x: x[0])})
Output
{'D': 2, 'k': 4}
Related
I have a list of pairs.The list contains items of [x,y].I would like to make list or dictionary making the left item the key and right the value.The list maybe contains multiple times the same key. I want to sum the values and keep one time the key.
E.x
pairs[0]=['3106124650', 2.86]
pairs[1]=['3106124650', 8.86]
pairs[2]=['5216154610', 23.77]
I want to keep '3106124650' one time and sum the values.So my new list or dictionary will contain one time this key with value 11.72.
'3106124650',11.72
Here's a way. For large datasets, numpy will probably be faster though.
import collections
result = collections.defaultdict(lambda : 0)
for k,v in pairs:
result[k]+=v
sumdict = dict()
for i, v in pairs:
sumdict[i] = v + sumdict.get(i, 0)
li=[['a',1],['a',2],['b',3],['c',4]]
d={}
for w in li:
d[w[0]]=w[1]+d.get(w[0],0)
Output:{'a': 3, 'b': 3, 'c': 4}
you can try this:
d={}
for entry in pairs:
if entry[0] in d:
d[entry[0]]+=entry[1]
else:
d[entry[0]]=entry[1]
So what I was trying to do was output the string "33k22k11k", which is just the last value followed by the reversed last key followed by the second last value followed by the second last reversed key and so on. I'm not sure how to get the reversed key value for the specific loop that I am in. From the code I currently I have, I get the output:
dict = {"k1":1, "k2":2, "k3":3}
current=""
current_k=""
for k,v in dict.items():
for i in k:
current_k=i+current_k
current=str(v)+current_k+current
print(current)
print(current_k)
33k2k1k22k1k11k
3k2k1k
Edited
First of all, if you are on python < 3.6, dict does not keep the order of items. You might want to use collections.OrderedDict for your purpose.
d = {"k1":1, "k2":2, "k3":3}
d.keys()
# dict_keys(['k2', 'k1', 'k3'])
whereas,
d = OrderedDict()
d['k1'] = 1
d['k2'] = 2
d['k3'] = 3
d.keys()
# odict_keys(['k1', 'k2', 'k3'])
With our new d, you can either add the key and values and reverse it:
res = ''
for k, v in d.items():
res += str(k) + str(v)
res[::-1]
# '33k22k11k'
or reversely iterate:
res = ''
for k, v in reversed(d.items()):
res += str(v)[::-1] + str(k)[::-1]
res
# '33k22k11k'
I may be wrong but it seems like you would want to reset the value of current_k each time you access a new key
dict = {"k1":1, "k2":2, "k3":3}
current=""
for k,v in dict.items():
current_k=""
for i in k:
current_k=i+current_k
current=str(v)+current_k+current
print(current)
print(current_k)
Why not simply do:
print(''.join([a+str(b) for a,b in dict.items()])[::-1])
Output:
"33k22k11k"
But if the values are different from the keys, do:
print(''.join([str(b)[::-1]+a for a,b in dict.items()[::-1]]))
You can use the Python map function to create the reversed string(using f-string) for each key/value pair and then join it.
dict1 = {"k1":1, "k2":2, "k3":3}
new_dict = "".join(map(lambda k, v: f'{k}{v}'[::-1] , dict1.keys(), dict1.values()))
Output:
33k22k11k
You can do something like this perhaps:
dict = {"k1":1, "k2":2, "k3":3}
print("".join(list(reversed([str(v)+"".join(reversed(k)) for k, v in dict.items()]))))
Output:
33k22k11k
I am working on a function
def common_words(dictionary, N):
if len(dictionary) > N:
max(dictionary, key=dictionary.get)
Description of the function is:
The first parameter is the dictionary of word counts and the second is
a positive integer N. This function should update the dictionary so
that it includes the most common (highest frequency words). At most N
words should be included in the dictionary. If including all words
with some word count would result in a dictionary with more than N
words, then none of the words with that word count should be included.
(i.e., in the case of a tie for the N+1st most common word, omit all
of the words in the tie.)
So I know that I need to get the N items with the highest values but I am not sure how to do that. I also know that once I get N items that if there are any duplicate values that I need to pop them out.
For example, given
k = {'a':5, 'b':4, 'c':4, 'd':1}
then
common_words(k, 2)
should modify k so that it becomes {'a':5}.
Here's my algorithm for this problem.
Extract the data from the dictionary into a list and sort it in descending order on the dictionary values.
Clear the original dictionary.
Group the sorted data into groups that have the same value.
Re-populate the dictionary with the all (key, value) pairs from each group in the sorted list if that will keep the total dictionary size <= N. If adding a group would make the total dictionary size > N, then return.
The grouping operation can be easily done using the standard itertools.groupby function.
To perform the sorting and grouping we need an appropriate key function, as described in the groupby, list and sorted docs. Since we need the second item of each tuple we could use
def keyfunc(t):
return t[1]
or
keyfunc = lambda t: t[1]
but it's more efficient to use operator.itemgetter.
from operator import itemgetter
from itertools import groupby
def common_words(d, n):
keyfunc = itemgetter(1)
lst = sorted(d.items(), key=keyfunc, reverse=True)
d.clear()
for _, g in groupby(lst, key=keyfunc):
g = list(g)
if len(d) + len(g) <= n:
d.update(g)
else:
break
# test
data = {'a':5, 'b':4, 'c':4, 'd':1}
common_words(data, 4)
print(data)
common_words(data, 2)
print(data)
output
{'c': 4, 'd': 1, 'b': 4, 'a': 5}
{'a': 5}
my algorithm as below
1st build tuple list from dictionary sorted based on value from
largest to smallest
check for if item[N-1] match item[N] value, if yes, drop item[N-1]
(index start from 0, so -1 there)
finally, convert the slice of tuple list up to N element back to
dict, may change to use OrderedDict here if wanna retain the items order
it will just return the dictionary as it is if the dictionary length is less than N
def common_words(dictionary, N):
if len(dictionary) > N:
tmp = [(k,dictionary[k]) for k in sorted(dictionary, key=dictionary.get, reverse=True)]
if tmp[N-1][1] == tmp[N][1]:
N -= 1
return dict(tmp[:N])
# return [i[0] for i in tmp[:N]] # comment line above and uncomment this line to get keys only as your title mention how to get keys
else:
return dictionary
# return dictionary.keys() # comment line above and uncomment this line to get keys only as your title mention how to get keys
>>> common_words({'a':5, 'b':4, 'c':4, 'd':1}, 2)
{'a': 5}
OP wanna modify input dictionary within function and return None, it can be modified as below
def common_words(dictionary, N):
if len(dictionary) > N:
tmp = [(k,dictionary[k]) for k in sorted(dictionary, key=dictionary.get, reverse=True)]
if tmp[N-1][1] == tmp[N][1]:
N -= 1
# return dict(tmp[:N])
for i in tmp[N:]:
dictionary.pop(i[0])
>>> k = {'a':5, 'b':4, 'c':4, 'd':1}
>>> common_words(k, 2)
>>> k
{'a': 5}
I have a set of reactions (keys) with values (0.0 or 100) stored in mydict.
Now I want to place non zero values in a new dictionary (nonzerodict).
def nonzero(cmod):
mydict = cmod.getReactionValues()
nonzerodict = {}
for key in mydict:
if mydict.values() != float(0):
nonzerodict[nz] = mydict.values
print nz
Unfortunately this is not working.
My questions:
Am I iterating over a dictionary correctly?
Am I adding items to the new dictionary correctly?
You are testing if the list of values is not equal to float(0). Test each value instead, using the key to retrieve it:
if mydict[key] != 0:
nonzerodict[key] = mydict[key]
You are iterating over the keys correctly, but you could also iterate over the key-value pairs:
for key, value in mydict.iteritems():
if value != 0:
nonzerodict[key] = value
Note that with floating point values, chances are you'll have very small values, close to zero, that you may want to filter out too. If so, test if the value is close to zero instead:
if abs(value) > 1e-9:
You can do the whole thing in a single dictionary expression:
def nonzero(cmod):
return {k: v for k, v in cmod.getReactionValues().iteritems() if abs(v) > 1e-9}
Its simple and you can it by below way -
>>> d = {'a':4,'b':2, 'c':0}
>>> dict((k,v) for k,v in d.iteritems() if v!=0)
{'a': 4, 'b': 2}
>>>
Replace if condition in you code with:
if mydict[key]:
nonzerodict[key] = mydict[key]
Your solution can be further simplified as:
def nonzero(cmod):
mydict = cmod.getReactionValues()
nonzerodict = {key: value for key, value in mydict.iteritems() if value}
I've two dictionaries, output of factorint from sympy.ntheory. I need to merge them so that the common keys gets their values summed up, i.e. MergedDict[key] = Dict1[key] + Dict2[key], while unique keys remain same.
Also I need to get a merged dictionary with the common keys being differenced, i.e. MergedDict[key] = Dict1[key] - Dict2[key]. Here Dict2 keys will be always a subset of Dict1 keys, so no problem of negative numbers.
I've tried to follow this question. But I'm unable to make it work. So far my approach has been as follows:
from sympy.ntheory import factorint
from collections import defaultdict
d=factorint(12)
dd = defaultdict(lambda: defaultdict(int))
for key, values_dict in d.items():
for date, integer in values_dict.items():
dd[key] += integer
for n in range(2,6):
u = factorint(n)
for key, values_dict in u.items():
for date, integer in values_dict.items():
dd[key] += integer
It gives the error AttributeError: 'int' object has no attribute 'items'. The code above in only for the summing up part. Yet to do anything on the differencing part, assuming that summing up can be changed to work for differencing in case of common keys.
Not sure what you goal is but factorint gives you key/value pairs of ints so you should be summing the values, you are trying to call items on each val from the dict which is an integer and obviously not going to work:
from sympy.ntheory import factorint
from collections import defaultdict
d=factorint(12)
dd = defaultdict(int)
for key, val in d.items():
dd[key] += val
for n in range(2, 6):
u = factorint(n)
for key, val in u.items():
dd[key] += val
print(dd)
Output:
defaultdict(<type 'int'>, {2: 5, 3: 2, 5: 1})
factorint being a dict cannot have duplicate keys so the first loop cann be done using update:
d = factorint(12)
dd = defaultdict(int)
dd.update(d)
for n in range(2, 6):
u = factorint(n)
for key, val in u.items():
dd[key] += val
It seems that collections.Counter can do most of what you want. It might be as simple as (untested, I do not have sympy installed):
from collections import Counter
cnt1 = Counter(Dict1)
cnt2 = Counter(Dict2)
sum_cnt = cnt1 + cnt2
diff_cnt = cnt1 - cnt2