How to sum the unique keys in dictionary? - python

I have a bunch of key values in a list:
all = [('a' : '87'), ('b': '72'), ('a' : '39'), ('b' : '84')]
How can I quickly sum up all of the values that have the same keys?
Output:
a = 126
b = 156

You can't have duplicate keys in a dictionary. Later matching keys overwrite earlier ones. Also dict is a really bad name as it hides the dict class type:
>>> D = {'a' : '87', 'b': '72', 'a' : '39', 'b' : '84'}
>>> D
{'b': '84', 'a': '39'}
If you store your data as pairs in a list, however:
>>> L=[('a','87'), ('b', '72'), ('a','39'), ('b','84')]
>>> L
[('a', '87'), ('b', '72'), ('a', '39'), ('b', '84')]
A defaultdict creates its default type for non-existent keys, so D[k] below will be zero if the key is not yet present:
>>> from collections import defaultdict
>>> D = defaultdict(int)
>>> for k,v in L:
... D[k] += int(v)
...
>>> D
defaultdict(<class 'int'>, {'b': 156, 'a': 126})
>>> dict(D)
{'b': 156, 'a': 126}

First, in Python, as far as I know, there is no data type representation as this:
[('a' : '87'), ('b': '72'), ('a' : '39'), ('b' : '84')],
Probably, you were referring to a dict, which you cannot have with dulplicate keys by the way.
This answer will be very similar to #Mark Tolonen's answer, except for using only primitive data types without module:
>>> a = [('a','87'), ('b','72'), ('a','39'), ('b','84')]
>>> d = {}
>>>
>>> for k,v in a:
#if k already exists in d, just add up the values
if k in d:
d[k] += int(v)
#otherwise, create a (k,int(v)) pair in the dict
else:
d[k] = int(v)
>>> d
{'a': 126, 'b': 156}

Related

I want to sort a dictionary descending by number and then ascending alphabetically

I have this code
L = ['c', 'c', 'b', 'a','b']
from collections import Counter
import numpy as np
x = Counter(L)
dict1 = {k: v for k, v in sorted(x.items(), key=lambda item: -item[1])}
print(dict1)
It gives me {'c': 2, 'b': 2, 'a': 1}
But I want it to return me this: {'b': 2,'c': 2, 'a': 1}
if I turn it into a list and use sorted It will return me this [('a', 1), ('b', 2), ('c', 2)] which is not what I want, because so, the list will lose the descending sort by number.
b and c have the same precedence since they have the same value. Thus, their order is maintained, and since c appeared first in L, it will also appear first in x and in the dict comprehension expression from it. If you want b to come before c you could explicitly add a secondary key to the key lambda:
dict1 = {k: v for k, v in sorted(x.items(), key=lambda item: (-item[1], item[0]))}
# Here ---------------------------------------------------------------^

How to get a list which is a value of a dictionary by a value from the list?

I have the following dictionary :
d = {'1' : [1, 2, 3, 4], '2' : [10, 20, 30, 40]}
How do I get the corresponding key I'm searching by a value from one of the lists?
Let's say I want key '1' if I'm looking for value 3 or key '2' if I'm looking for value 10.
You can reverse the dictionary into this structure to do that kind of lookup:
reverse_d = {
1: '1',
2: '1',
3: '1',
4: '1',
10: '2',
…
}
which can be built by looping over each value of each key:
reverse_d = {}
for key, values in d.items():
for value in values:
reverse_d[value] = key
or more concisely as a dict comprehension:
reverse_d = {value: key for key, values in d.items() for value in values}
Lookups are straightforward now!
k = reverse_d[30]
# k = '2'
This only offers better performance than searching through the whole original dictionary if you do multiple lookups, though.
You can use a generator expression with a filtering condition, like this
>>> def get_key(d, search_value):
... return next(key for key, values in d.items() if search_value in values)
...
>>> get_key(d, 10)
'2'
>>> get_key(d, 2)
'1'
If none of the keys contain the value being searched for, None will be returned.
>>> get_key(d, 22)
None
This is my first time to answer question. How about this method?
def get_key(d,search_value):
res = []
for v in d.items():
if search_value in v[1]:
res.append(v[0])
return res
>>> D = {'a':[2,2,3,4,5],'b':[5,6,7,8,9]}
>>> getkey.get_key(D,2)
['a']
>>> getkey.get_key(D,9)
['b']
>>> getkey.get_key(D,5)
['a', 'b']

Print Value of Key in Lists of Dicts in Python

I am trying to print the value of a specific key in a list of dicts:
eg:
list = [{'a' : 123, 'b': 'xyz', 'c': [1,2]}, {'a' : 456, 'b': 'cde', 'c': [3,4]}]
I was hoping to be able to print the following for each dict:
print ("a: ", a)
print ("b: ", b)
If you're guaranteed those keys exist, a nice solution using operator.itemgetter:
from operator import itemgetter
# Renamed your list; don't name variables list
for a, b in map(itemgetter('a', 'b'), mylist):
print("a:", a)
print("b:", b)
The above is just a slightly optimized version of the import free code, pushing the work of fetching values to the builtins instead of doing it over and over yourself.
for d in mylist: # Renamed your list; don't name variables list
print("a:", d['a'])
print("b:", d['b'])
Oh, and for completeness (Aaron Hall is right that it's nice to avoid redundant code), a tweak to itemgetter usage to observe DRY rules:
keys = ('a', 'b')
for values in map(itemgetter(*keys), mylist):
for k, v in zip(keys, values):
print(k, v, sep=": ")
How about some nested loops, to avoid hard-coding it?
for dictionary in list: # rename list so you don't overshadow the builtin list
for key in ('a', 'b'):
print(key + ':', dictionary[key])
which should output:
a: 123
b: xyz
a: 456
b: cde
lst = [{'a' : 123, 'b': 'xyz', 'c': [1,2]}, {'a' : 456, 'b': 'cde', 'c': [3,4]}]
output=['a','b']
for dct in lst:
for k in output:
print(k+': '+str(dct[k]))

What is the best way to search for a key in multiple dictionaries in Python

I know we can search for a key in Python like this:
if key in myDict:
#Do something here
I know we can extend this and search for the key in multiple dictionaries using elif statement
if key in myDict_1:
#Do something here
elif key in myDict_2:
#Do something here
or by doing
if key in (myDict_1.keys() + myDict_2.keys()):
#Do something here
But is there a more succinct way to search for key in Python in two different dicts without using if-else or adding the list of keys explicitly ?
The answer to your question as written is:
if any(key in d for d in dicts):
# do something
If you need to know which dictionary or dictionaries contain the key, you can use itertools.compress():
>>> d1 = dict(zip("kapow", "squee"))
>>> d2 = dict(zip("bar", "foo"))
>>> d3 = dict(zip("xyz", "abc"))
>>> dicts = d1, d2, d3
>>> from pprint import pprint
>>> pprint(dicts)
({'a': 'q', 'k': 's', 'o': 'e', 'p': 'u', 'w': 'e'},
{'a': 'o', 'b': 'f', 'r': 'o'},
{'x': 'a', 'y': 'b', 'z': 'c'})
>>> from itertools import compress
>>> for d_with_key in compress(dicts, ("a" in d for d in dicts)):
... print(d_with_key)
...
{'a': 'q', 'p': 'u', 'k': 's', 'w': 'e', 'o': 'e'}
{'a': 'o', 'r': 'o', 'b': 'f'}
The correct way would be as Zero wrote:
if any(key in d for d in dicts): # do something
Fixing after reading comments below, thanks to #jwodder:
But you can also create a tuple of the keys of both (or more) dictionaries using the itertools.chain function.
>>> a = {1:2}
>>> b = {3:4}
>>> c = {5:6, 7:8}
>>> print(tuple(itertools.chain(a, b, c)))
(1, 3, 5, 7)
so you also can :
if x in tuple(itertools.chain(a, b, c)):
# Do something
A little list comprehension is also possible here; if you're simply trying to ascertain if a key is in a container of dicts, any() does exactly that; if you want to get the dict (or dicts) back and work with them, perhaps something like this would suffice:
>>> def get_dicts_with_key(some_key, *dicts):
... return [d for d in dicts if some_key in d]
>>> dict1 = {"hey":123}
>>> dict2 = {"wait":456}
>>> get_dicts_with_key('hey', dict1, dict2)
[{'hey': 123}]
>>> get_dicts_with_key('wait', dict1, dict2)
[{'wait': 456}]
>>> get_dicts_with_key('complaint', dict1, dict2)
[]
If the keys were present in either dict, both would be returned, as such:
>>> dict1['complaint'] = 777
>>> dict2['complaint'] = 888
>>> get_dicts_with_key('complaint', dict1, dict2)
[{'complaint': 777, 'hey': 123}, {'complaint': 888, 'wait': 456}]
>>>
Why don't you put your dicts in an iterable like a list and simple loop over then? You can express it as a function like so.
def has_key(key, my_dicts):
for my_dict in my_dicts:
if key in my_dict:
return True
return False
It would be used like so.
>>> dict1 = {'a':1, 'b': 2}
>>> dict2 = {'b':10, 'c': 11}
>>> has_key('b', [dict1, dict2])
True

python get all keys in subdictorionaries

In python, if I have a dictionary with sub dictionaries
d = {
'a' : {
'aa': {},
'ab': {},
},
'b' : {
'ba': {},
'bb': {},
}
}
how I can get the keys of every sub dictionary?
d.keys()
d['a'].keys()
d['b'].keys()
this is the normal way , but if I have many subdirectories, how I can get the keys of every sub dictionary ?
EDIT
I need the keys to access in a dictionary with five or more levels,
d[k1][k2][k3][k4][k5]
in some case I need the information "under" the k2 key, in other case "under" the k3 key, etc.
If you need the keys of all levels, you can recurse:
def nested_keys(d):
yield d.keys()
for value in d.values():
if isinstance(value, dict):
for res in nested_keys(value):
yield res
This is a generator function, you'd loop over the output or call list on it. This yields sequences of keys, not individual keys. In Python 3, that means you get dictionary views, for example, and empty dictionaries are included:
>>> d = {
... 'a' : {
... 'aa': {},
... 'ab': {},
... },
... 'b' : {
... 'ba': {},
... 'bb': {},
... }
... }
>>> def nested_keys(d):
... yield d.keys()
... for value in d.values():
... if isinstance(value, dict):
... for res in nested_keys(value):
... yield res
...
>>> for keys in nested_keys(d):
... print keys
...
['a', 'b']
['aa', 'ab']
[]
[]
['ba', 'bb']
[]
[]
This isn't all that useful, really, as you don't know what dictionary the keys belonged to.
This solution works for arbitrary level nested dictionaries
d = {
'a' : {
'aa': {},
'ab': {},
},
'b' : {
'ba': {},
'bb': {},
}
}
from itertools import chain
def rec(current_dict):
children = []
for k in current_dict:
yield k
if isinstance(current_dict[k], dict):
children.append(rec(current_dict[k]))
for k in chain.from_iterable(children):
yield k
print list(rec(d))
# ['a', 'b', 'aa', 'ab', 'ba', 'bb']
This depends if you have dictionaries in the subdictionaries or not. You can create a function that will check the types via recursion
def checksubtype(d):
# d is a dictionary check the subtypes.
for k in d:
if type(d[k]) == type(d):
print 'key', k, 'contains a dictionary'
checktype(d[k])
else:
print 'key', k, 'has type', type(d[k])
>>> d = {'a': {'aa': [1, 2, 3], 'bb': [3, 4]}, 'b': {'ba': [5, 6], 'bb': [7, 8]}}
>>> checksubtype(d)
key a contains a dictionary
key aa has type <type 'list'>
key bb has type <type 'list'>
key b contains a dictionary
key ba has type <type 'list'>
key bb has type <type 'list'>
I used a direct check of type rather than isinstance in order to show more obviously what is meant.

Categories