How to sort keys of dict by values? - python

I have a dict {'a': 2, 'b': 0, 'c': 1}.
Need to sort keys by values so that I can get a list ['b', 'c', 'a']
Is there any easy way to do this?

sorted_keys = sorted(my_dict, key=my_dict.get)

>>> d={'a': 2, 'b': 0, 'c': 1}
>>> [i[0] for i in sorted(d.items(), key=lambda x:x[1])]
['b', 'c', 'a']

try this:
import operator
lst1 = sorted(lst.items(), key=operator.itemgetter(1))

There's a simple way to do it.
You can use .items() to get key-value and use sorted to sort them accordingly.
dictionary = sorted(dictionary.items(),key=lambda x:x[1])

>>> d = {'a':2, 'b':0, 'c':1}
>>> sor = sorted(d.items(), key=lambda x: x[1])
>>> sor
[('b', 0), ('c', 1), ('a', 2)]
>>> for i in sor:
... print i[0]
...
b
c
a

Related

Set of Dictionary elements

I want to create a set of dictionaries in python. I know how to make a list of dictionaries and convert it to set, but I want to add a dictionary to a set. Can anyone help me?
I got this error when I try below code:
"Exception has occurred: TypeError unhashable type: 'dict'"
C = set()
A = {'a':1, 'c':2, 'd':3}
B = {'c':3, 'd':4, 2:5 }
C.add(A)
C.add(B)
Thanks
For the below:
C = set()
A = {'a':1, 'c':2, 'd':3}
B = {'c':3, 'd':4, 2:5 }
You could do something like this to combine all the above into a single set. I will use an union operator '|' to achieve this.
{i for i in A.items()} | {i for i in B.items()}
This results to:
{('a', 1), ('c', 2), ('c', 3), ('d', 3), ('d', 4), (2, 5)}
** Extra Information **
If you knew from the start that dictionary B does not contain any of the keys found in dictionary A, you could do something like the below to combine the two dictionaries:
For example:
A = {'a':1, 'c':2, 'd':3}
B = {'e':3, 'f':4, 2:5 }
from collections import Counter
C = Counter(A) + Counter(B)
C equates to the below:
Counter({'a': 1, 'c': 2, 'd': 3, 'e': 3, 'f': 4, 2: 5})

how to identify relationship/mapping between the two list in python?

I have created two list.
list1= [a,b,c,a,d]
list2=[1,2,3,4,5]
I want to find relationship between this two list based on index position i.e
In list1 a is repeated 2 times index 0,3 .in list2 index 0,3 values are 1 ,4 the relation is a one to many is a:{1,4}
next b not repeated in list 1 and it index is 1 and list2 index 1 value is 2 ,the relation is one to one b:{2}
my expected output will be {a:{1,4},b:{2},c:{3},d:{5}}
I'd use a defaultdict:
from collections import defaultdict
list1 = ['a', 'b', 'c', 'a', 'd']
list2 = [1, 2, 3, 4, 5]
result = defaultdict(set)
for value1, value2, in zip(list1, list2):
result[value1].add(value2)
print(dict(result))
outputs
{'a': {1, 4}, 'b': {2}, 'c': {3}, 'd': {5}}
You can use a combination of dictionary and list comprehension to do this:
{x: [list2[i] for i, j in enumerate(list1) if j == x] for x in list1}
output:
{'a': [1, 4], 'b': [2], 'c': [3], 'd': [5]}
a = ['a', 'b', 'c', 'a', 'd']
b = [1, 2, 3, 4, 5]
ret = {}
for idx, _a in enumerate(a):
value = ret.get(_a, ret.setdefault(_a, []))
value.append(b[idx])
And ret will be the output
Option is to zip the two lists:
L = list(zip(list1, list2))
Result:
[('a', 1), ('b', 2), ('c', 3), ('a', 4), ('d', 5)]
Use it to create a dictionary with sets as values:
D ={}
for key in L:
if key[0] not in D:
D[key[0]] = {key[1]}
else:
D[key[0]].add(key[1])
I would not do it this way in real code, but this approach is mildly entertaining and perhaps educational.
from collections import defaultdict
from itertools import groupby
from operator import itemgetter
xs = ['a', 'b', 'c', 'a', 'd']
ys = [1, 2, 3, 4, 5]
d = {
x : set(y for _, y in group)
for x, group in groupby(sorted(zip(xs, ys)), key = itemgetter(0))
}
print(d) # {'a': {1, 4}, 'b': {2}, 'c': {3}, 'd': {5}}
It's not from pure python, as this question tagged with pandas I tried this way.
Option-1
df=pd.DataFrame({'l1':list1,'l2':list2})
res1=df.groupby('l1').apply(lambda x:x.l2.values.tolist()).to_dict()
Option-2
print df.groupby('l1')['l2'].unique().to_dict()
Output:
{'a': [1, 4], 'c': [3], 'b': [2], 'd': [5]}

Converting list to dictionary with list elements as index - Python

From Python: create dict from list and auto-gen/increment the keys (list is the actual key values)?, it's possible to create a dict from a list using enumerate to generate tuples made up of incremental keys and elements in life, i.e.:
>>> x = ['a', 'b', 'c']
>>> list(enumerate(x))
[(0, 'a'), (1, 'b'), (2, 'c')]
>>> dict(enumerate(x))
{0: 'a', 1: 'b', 2: 'c'}
It is also possible to reverse the key-value by iterating through every key in the dict (assuming that there is a one-to-one mapping between key-value pairs:
>>> x = ['a', 'b', 'c']
>>> d = dict(enumerate(x))
>>> {v:k for k,v in d.items()}
{'a': 0, 'c': 2, 'b': 1}
Given the input list ['a', 'b', 'c'], how can achieve the dictionary where the elements as the key and incremental index as values without trying to loop an additional time to reverse the dictionary?
How about simply:
>>> x = ['a', 'b', 'c']
>>> {j:i for i,j in enumerate(x)}
{'a': 0, 'c': 2, 'b': 1}

How would I make a dictionary from a list of tuples?

How would I go about making a dictionary from a list like this:
list = [('a', [10,3]), ('a', [30,20]), ('b', [96,45]), ('b', [4,20])]
The result I want is:
dict = { 'a':[10,3,30,20], 'b':[96,45,4,20] }
You can use collections.defaultdict for this:
>>> from collections import defaultdict
>>> lst = [('a', [10,3]), ('a', [30,20]), ('b', [96,45]), ('b', [4,20])]
>>> dct = defaultdict(list)
>>> for x, y in lst:
... dct[x] += y
...
>>> dct
defaultdict(<class 'list'>, {'a': [10, 3, 30, 20], 'b': [96, 45, 4, 20]})
>>>
Or, if you want to avoid the import, try dict.setdefault:
>>> lst = [('a', [10,3]), ('a', [30,20]), ('b', [96,45]), ('b', [4,20])]
>>> dct = {}
>>> for x, y in lst:
... dct.setdefault(x, []).extend(y)
...
>>> dct
{'a': [10, 3, 30, 20], 'b': [96, 45, 4, 20]}
>>>
This also works: (it assumes your items are already sorted by key. If not, then just used sortedi(items) instead)
from itertools import groupby
from operator import itemgetter
items = [('a', [10,3]), ('a', [30,20]), ('b', [96,45]), ('b', [4,20])]
d = dict((key, sum((list_ for _key, list_ in group), []))
# for each group create a key, value tuple. with the value being the
# concatenation of all the lists in the group. eg. [10, 3] + [30, 20]
for key, group in groupby(items, itemgetter(0)))
# group elements in items by the first item in each element

create dictionary from list - in sequence

I would like to create a dictionary from list
>>> list=['a',1,'b',2,'c',3,'d',4]
>>> print list
['a', 1, 'b', 2, 'c', 3, 'd', 4]
I use dict() to produce dictionary from list
but the result is not in sequence as expected.
>>> d = dict(list[i:i+2] for i in range(0, len(list),2))
>>> print d
{'a': 1, 'c': 3, 'b': 2, 'd': 4}
I expect the result to be in sequence as the list.
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
Can you guys please help advise?
Dictionaries don't have any order, use collections.OrderedDict if you want the order to be preserved. And instead of using indices use an iterator.
>>> from collections import OrderedDict
>>> lis = ['a', 1, 'b', 2, 'c', 3, 'd', 4]
>>> it = iter(lis)
>>> OrderedDict((k, next(it)) for k in it)
OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)])
Dictionary is an unordered data structure. To preserve order use collection.OrderedDict:
>>> lst = ['a',1,'b',2,'c',3,'d',4]
>>> from collections import OrderedDict
>>> OrderedDict(lst[i:i+2] for i in range(0, len(lst),2))
OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)])
You could use the grouper recipe: zip(*[iterable]*n) to collect the items into groups of n:
In [5]: items = ['a',1,'b',2,'c',3,'d',4]
In [6]: items = iter(items)
In [7]: dict(zip(*[items]*2))
Out[7]: {'a': 1, 'b': 2, 'c': 3, 'd': 4}
PS. Never name a variable list, since it shadows the builtin (type) of the same name.
The grouper recipe is easy to use, but a little harder to explain.
Items in a dict are unordered. So if you want the dict items in a certain order, use a collections.OrderedDict (as falsetru already pointed out):
In [13]: collections.OrderedDict(zip(*[items]*2))
Out[13]: OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)])

Categories

Resources