put top 2 biggest keys and values of dictionary in another dictionary - python

Here is my dictionary:
d = {'a': 100, 'b': 200, 'c': 300, 'd': 350}
I can find top 2 keys with biggest values and put them to the list:
sorted(d, key=d.get, reverse=True)[:2]
But what should I do to put top 2 biggest keys and values in another dictionary instead of list?
Thanks.

Sort dict.items based on values.
Slice the sorted list.
Pass the sliced list to dict().
Pass the dict returned from dict() to update method of the dict you want to modify.
Demo:
>>> d = {'a': 100, 'b': 200, 'c': 300, 'd': 350}
>>> dic = {}
>>> dic.update(dict(sorted(d.items(), key=lambda x:x[1], reverse=True)[:2]))
>>> dic
{'c': 300, 'd': 350}
Using operator.itemgetter:
from operator import itemgetter
dic = {}
dic.update(dict(sorted(d.items(), key=itemgetter(1), reverse=True)[:2]))
If dictionary is huge then heapq.nlargest will be more efficient than sorted:
>>> import heapq
>>> dic = {}
>>> dic.update({k:d[k] for k in heapq.nlargest(2, d, key=d.get)})
>>> dic
{'c': 300, 'd': 350}

dict(sorted(d.items(), key=lambda x:x[1], reverse=True)[:2])
update something:
thanks for the one upvotes.
I saw no one answered this question so I decided to answer it,but when I submitted my answer ,it already ranked 3rd.
I am glab to see the VERY USEFUL form "lambda x:x[1]" showed up in the earlist answer.
I strongly recommend this form.Simple yet Powerful in descripting idea.
I also strongly wonder: the one downvote the lambda form-what's up with lambda? any better idea to share with us?

Related

Making list of dictionaries into a single dictiionary python [duplicate]

How can I turn a list of dicts like [{'a':1}, {'b':2}, {'c':1}, {'d':2}], into a single dict like {'a':1, 'b':2, 'c':1, 'd':2}?
Answers here will overwrite keys that match between two of the input dicts, because a dict cannot have duplicate keys. If you want to collect multiple values from matching keys, see How to merge dicts, collecting values from matching keys?.
This works for dictionaries of any length:
>>> result = {}
>>> for d in L:
... result.update(d)
...
>>> result
{'a':1,'c':1,'b':2,'d':2}
As a comprehension:
# Python >= 2.7
{k: v for d in L for k, v in d.items()}
# Python < 2.7
dict(pair for d in L for pair in d.items())
In case of Python 3.3+, there is a ChainMap collection:
>>> from collections import ChainMap
>>> a = [{'a':1},{'b':2},{'c':1},{'d':2}]
>>> dict(ChainMap(*a))
{'b': 2, 'c': 1, 'a': 1, 'd': 2}
Also see:
What is the purpose of collections.ChainMap?
Little improvement for #dietbuddha answer with dictionary unpacking from PEP 448, for me, it`s more readable this way, also, it is faster as well:
from functools import reduce
result_dict = reduce(lambda a, b: {**a, **b}, list_of_dicts)
But keep in mind, this works only with Python 3.5+ versions.
This is similar to #delnan but offers the option to modify the k/v (key/value) items and I believe is more readable:
new_dict = {k:v for list_item in list_of_dicts for (k,v) in list_item.items()}
for instance, replace k/v elems as follows:
new_dict = {str(k).replace(" ","_"):v for list_item in list_of_dicts for (k,v) in list_item.items()}
unpacks the k,v tuple from the dictionary .items() generator after pulling the dict object out of the list
For flat dictionaries you can do this:
from functools import reduce
reduce(lambda a, b: dict(a, **b), list_of_dicts)
You can use join function from funcy library:
from funcy import join
join(list_of_dicts)
>>> L=[{'a': 1}, {'b': 2}, {'c': 1}, {'d': 2}]
>>> dict(i.items()[0] for i in L)
{'a': 1, 'c': 1, 'b': 2, 'd': 2}
Note: the order of 'b' and 'c' doesn't match your output because dicts are unordered
if the dicts can have more than one key/value
>>> dict(j for i in L for j in i.items())
If you don't need the singleton dicts anymore:
>>> L = [{'a':1}, {'b':2}, {'c':1}, {'d':2}]
>>> dict(map(dict.popitem, L))
{'a': 1, 'b': 2, 'c': 1, 'd': 2}
dict1.update( dict2 )
This is asymmetrical because you need to choose what to do with duplicate keys; in this case, dict2 will overwrite dict1. Exchange them for the other way.
EDIT: Ah, sorry, didn't see that.
It is possible to do this in a single expression:
>>> from itertools import chain
>>> dict( chain( *map( dict.items, theDicts ) ) )
{'a': 1, 'c': 1, 'b': 2, 'd': 2}
No credit to me for this last!
However, I'd argue that it might be more Pythonic (explicit > implicit, flat > nested ) to do this with a simple for loop. YMMV.
this way worked for me:
object = [{'a':1}, {'b':2}, {'c':1}, {'d':2}]
object = {k: v for dct in object for k, v in dct.items()}
printing object:
object = {'a':1,'b':2,'c':1,'d':2}
thanks Axes
>>> dictlist = [{'a':1},{'b':2},{'c':1},{'d':2, 'e':3}]
>>> dict(kv for d in dictlist for kv in d.iteritems())
{'a': 1, 'c': 1, 'b': 2, 'e': 3, 'd': 2}
>>>
Note I added a second key/value pair to the last dictionary to show it works with multiple entries.
Also keys from dicts later in the list will overwrite the same key from an earlier dict.

Python sorting nested dictionary list

I am trying to sort a nested dictionary in Python.
Right now I have a dictionary of dictionaries. I was able to sort the outer keys using sorted on the list before I started building the dictionary, but I am unable to get the inner keys sorted at same time.
I've been trying to mess with the sorted API whereas still having problems with it.
Right now I have:
myDict = {'A': {'Key3':4,'Key2':3,'Key4':2,'Key1':1},
'B': {'Key4':1,'Key3':2,'Key2':3,'Key1':4},
'C': {'Key1':4,'Key2':2,'Key4':1,'Key3':3}};
But I would like:
myDict = {'A': {'Key1':1,'Key2':3,'Key3':4,'Key4':2},
'B': {'Key1':4,'Key2':3,'Key2':1,'Key4':1},
'C': {'Key1':4,'Key2':2,'Key3':3,'Key4':1}};
I appreciate the help!
>>> from collections import OrderedDict
>>> def sortedDict(items):
... return OrderedDict(sorted(items))
>>> myDict = {'A': {'Key3':4,'Key2':3,'Key4':2,'Key1':1},
... 'B': {'Key4':1,'Key3':2,'Key2':3,'Key1':4},
... 'C': {'Key1':4,'Key2':2,'Key4':1,'Key3':3}}
>>> sortedDict((key, sortedDict(value.items())) for key, value in myDict.items())

Changing many values in dictionary without using name of the keys

I want to change all values in dictionary to different ones.
For example, in a dictionary
dic = {'a': 1, 'b':2, 'c':3, 'd':4, 'e': 5, 'f':6}
lst = [100, 200, 300, 400, 500, 600]
I want to change dic's values to numbers in lst like
dic = {'a': 100 ,'b': 200 ... }.
Is there any way to change all the values without using the name of the keys? The length of my actual dictionary is about 100.
If you need to multiply each number in the dict by 100, you could iterate through all the values at once by using a dict comprehension.
dic = {'a': 1, 'b':2, 'c':3, 'd':4, 'e': 5, 'f':6}
dic = {k: v*100 for k, v in dic.items()}
If you want the numbers of the list specifically to be assigned to letters in the alphabet (in the same order), you can zip your list with small caps letters, and use this list to build your dict:
from string import ascii_lowercase
# you can do this with a dict comprehension
dic = {k: v for (k, v) in zip(ascii_lowercase, lst)}
# or equivalently, call the dict() built-in function
dic = dict(zip(ascii_lowercase, lst))
In this last example, the order of your list will be reflected by the order of the alphabet's letters. So that a will be 100, b will be 200, etc.
But you can't make a dict remember it's "order". There's no order in a dict, you can just pick the values and set them individually, not iterate through them with a guaranteed order (as stated in another answer, you'd need OrderedDict for that).
Short answer: No, dictionaries are not ordered in python, so there's no easy way to match up values.
Longer answer: Sort of, you can used Ordered Dictionaries.
dic={'a': 1, 'b':2, 'c':3, 'd':4, 'e': 5, 'f':6}
o_dic = OrderedDict(sorted(dic.items(), key=lambda t: t[0]))
lst=[100,200,300,400,500,600]
for index, key in enumerate(o_dic.keys()):
o_dic[key] = lst[index]

How do I find the keys in one dictionary that do not have a counterpart in another dictionary?

In Python, how do I find the keys in one dictionary that do not have a counterpart in another dictionary? The practical problem is that I have a dictionary of people that enrolled and a dictionary with their daily participation and I am trying to find the people that enrolled but did not participate, or are in the enrollments dictionary and not in the participation dictionary.
In the Python cookbook I found good code for the intersection enrollments and participation, or the intersection of the two dictionaries:
print "Intersection: ", filter(enrollments.has_key, participation.keys())
But I can't figure out how to extend this logic to the obverse (?) case. I have tried putting a not in front of participation.keys() but I get an error. Is there a way to extend the logic in the filter to my problem or another way to approach it altogether?
Use sets on the keys to find the difference:
>>> P = dict(zip('a b c d'.split(),[1,2,3,4]))
>>> E = dict(zip('a b e f'.split(),[6,7,8,9]))
>>> set(P)-set(E)
{'d', 'c'}
>>> set(E)-set(P)
{'f', 'e'}
Also, you can use a dictionary comprehension. It is a way to map a function across a dictionary, and/or filter the contents. The syntax means to return the key:value pair for each key and value in the dictionary's items where the key is not in another dictionary:
>>> {k:v for k,v in P.items() if k not in E}
{'d': 4, 'c': 3}
>>> {k:v for k,v in E.items() if k not in P}
{'f': 9, 'e': 8}
In Python 3, dict.keys() gives you a set-like view of the keys in a dictionary, so doing this is as simple as:
>>> enrolled = {'steve': 0, 'mike': 42, 'judy': 100}
>>> participated = {'judy': 5, 'mike': 10}
>>> enrolled.keys() - participated.keys()
{'steve'}
In Python 2, replace .keys() with .viewkeys()
You can use a lambda as the first argument to filter.
print "Intersection: ", filter(lambda x:x not in participation, enrollments)

How do I merge a list of dicts into a single dict?

How can I turn a list of dicts like [{'a':1}, {'b':2}, {'c':1}, {'d':2}], into a single dict like {'a':1, 'b':2, 'c':1, 'd':2}?
Answers here will overwrite keys that match between two of the input dicts, because a dict cannot have duplicate keys. If you want to collect multiple values from matching keys, see How to merge dicts, collecting values from matching keys?.
This works for dictionaries of any length:
>>> result = {}
>>> for d in L:
... result.update(d)
...
>>> result
{'a':1,'c':1,'b':2,'d':2}
As a comprehension:
# Python >= 2.7
{k: v for d in L for k, v in d.items()}
# Python < 2.7
dict(pair for d in L for pair in d.items())
In case of Python 3.3+, there is a ChainMap collection:
>>> from collections import ChainMap
>>> a = [{'a':1},{'b':2},{'c':1},{'d':2}]
>>> dict(ChainMap(*a))
{'b': 2, 'c': 1, 'a': 1, 'd': 2}
Also see:
What is the purpose of collections.ChainMap?
Little improvement for #dietbuddha answer with dictionary unpacking from PEP 448, for me, it`s more readable this way, also, it is faster as well:
from functools import reduce
result_dict = reduce(lambda a, b: {**a, **b}, list_of_dicts)
But keep in mind, this works only with Python 3.5+ versions.
This is similar to #delnan but offers the option to modify the k/v (key/value) items and I believe is more readable:
new_dict = {k:v for list_item in list_of_dicts for (k,v) in list_item.items()}
for instance, replace k/v elems as follows:
new_dict = {str(k).replace(" ","_"):v for list_item in list_of_dicts for (k,v) in list_item.items()}
unpacks the k,v tuple from the dictionary .items() generator after pulling the dict object out of the list
For flat dictionaries you can do this:
from functools import reduce
reduce(lambda a, b: dict(a, **b), list_of_dicts)
You can use join function from funcy library:
from funcy import join
join(list_of_dicts)
>>> L=[{'a': 1}, {'b': 2}, {'c': 1}, {'d': 2}]
>>> dict(i.items()[0] for i in L)
{'a': 1, 'c': 1, 'b': 2, 'd': 2}
Note: the order of 'b' and 'c' doesn't match your output because dicts are unordered
if the dicts can have more than one key/value
>>> dict(j for i in L for j in i.items())
If you don't need the singleton dicts anymore:
>>> L = [{'a':1}, {'b':2}, {'c':1}, {'d':2}]
>>> dict(map(dict.popitem, L))
{'a': 1, 'b': 2, 'c': 1, 'd': 2}
dict1.update( dict2 )
This is asymmetrical because you need to choose what to do with duplicate keys; in this case, dict2 will overwrite dict1. Exchange them for the other way.
EDIT: Ah, sorry, didn't see that.
It is possible to do this in a single expression:
>>> from itertools import chain
>>> dict( chain( *map( dict.items, theDicts ) ) )
{'a': 1, 'c': 1, 'b': 2, 'd': 2}
No credit to me for this last!
However, I'd argue that it might be more Pythonic (explicit > implicit, flat > nested ) to do this with a simple for loop. YMMV.
this way worked for me:
object = [{'a':1}, {'b':2}, {'c':1}, {'d':2}]
object = {k: v for dct in object for k, v in dct.items()}
printing object:
object = {'a':1,'b':2,'c':1,'d':2}
thanks Axes
>>> dictlist = [{'a':1},{'b':2},{'c':1},{'d':2, 'e':3}]
>>> dict(kv for d in dictlist for kv in d.iteritems())
{'a': 1, 'c': 1, 'b': 2, 'e': 3, 'd': 2}
>>>
Note I added a second key/value pair to the last dictionary to show it works with multiple entries.
Also keys from dicts later in the list will overwrite the same key from an earlier dict.

Categories