Sorting keys of same values alphabetically - python

I have a dictionary where I want to alphabetically sort the keys that have the same value assigned to them.
For example: {chai:1, apple:1, dom banana:1}
How do I sort these keys alphabetically?!
Thanks.

>>> from collections import defaultdict
>>> items = {'chai':1, 'apple':1, 'dom banana':1}
>>> d = defaultdict(list)
>>> for k,v in items.iteritems():
d[v].append(k)
>>> {k:sorted(v) for k,v in d.iteritems()}
{1: ['apple', 'chai', 'dom banana']}

sorted(k for k,v in D.iteritems() if v == 1)

Related

Sort a multilevel orderdict in Python?

I have a dict of type OrderDict as follows:
>>> from collections import OrderedDict
>>> d=OrderedDict()
>>> d['a']=(dict({'key1': 40}))
>>> d['a'].update(dict({'key2': 10}))
>>> d
OrderedDict([('a', {'key1': 40, 'key2': 10})])
>>> d.values()
odict_values([{'key1': 40, 'key2': 10}])
Now, I am trying to sort the created orderDict by the values of the dict, i.e., 10 and 40, but seems it keeps sorting by the keys. Here is what I am doing:
>>> sorted(list(d.values())[0], key=lambda x: x[1])
['key1', 'key2']
I am looking to get this:
{'a': {'key2': 10, 'key1': 40}}
In order to sort a dictionary by value, use d.get as the sort key:
{k: d[k] for k in sorted(d, key=d.get)}
The syntax you're looking for is this:
{k: v for k, v in sorted(d.items(), key=lambda x: x[1])}
This is the equivalent of list comprehension for dictionaries

How to reverse dictionary items and list keys grouped by common values [duplicate]

This question already has answers here:
Dictionary comprehension for swapping keys/values in a dict with multiple equal values
(3 answers)
Closed 2 years ago.
I have a dictionary that I want to group by the common values:
init_dict = {'00001': 'string1', '00002': 'string2', '00003': 'string1', '00004': 'string3', '00005': 'string2'}
I want to create a new dictionary that groups the values and lists the keys like this:
new_dict = {'string1': ['00001', '00003'], 'string2':['00002', '00004'], 'string3': ['00004']}
I tried many things and this is the closest I can get.
lookup = 'string1'
all_keys = []
for k, v in init_dict.items():
if v == lookup:
all_keys.append(k)
print(all_keys)
This produces the first list: ['00001', '00003'] so I thought I could somehow loop through a list of lookup values but can't since I'm working with strings. Is there a way to do this and is there a way that is relatively efficient because my initial dictionary has 53,000 items in it. Any help would be much appreciated as I've been trying different things for hours.
Use a defaultdict, specifying a list as default argument, and append the corresponding values from the dictionary:
from collections import defaultdict
d = defaultdict(list)
for k,v in init_dict.items():
d[v].append(k)
print(d)
defaultdict(list,
{'string1': ['00001', '00003'],
'string2': ['00002', '00005'],
'string3': ['00004']})
You can use defaultdict
result = defaultdict(list)
for k, v in init_dict.items():
result[v].append(k)
or itertools.groupby
result = {k: [x[0] for x in v] for k, v in
groupby(sorted(init_dict.items(), key=lambda kv: kv[1]), key=lambda kv: kv[1])}
You can also use a normal dict (instead of defaultdict):
new_dict = {}
for key, val in init_dict.items():
if val in new_dict:
new_dict[val].append(key)
else:
new_dict[val] = []
new_dict[val].append(key)
Output:
new_dict = {'string1': ['00001', '00003'],
'string2': ['00002', '00005'],
'string3': ['00004']}

Convert a list of dictionaries to a dictionary using dict constructor

I have the code snippet below that I want to get a dictionary from a list of dictionaries but getting global name item not found error. Wondering if it is possible to enumerate like below
l = [{1:{'item1':'value1'}},{2:{'item2':'value2'}}]
dic = dict(((k,v)) for k,v in item.items() for item in l)
print dic
You have your for ... in ... clauses backwards. They should go in the same order as if they were normal for-loops:
>>> l = [{1:{'item1':'value1'}},{2:{'item2':'value2'}}]
>>> dic = dict(((k,v)) for item in l for k,v in item.items())
>>> dic
{1: {'item1': 'value1'}, 2: {'item2': 'value2'}}
>>>
Also, I would like to point out that in Python 2.6+, you can use a dict comprehension for this:
>>> l = [{1:{'item1':'value1'}},{2:{'item2':'value2'}}]
>>> dic = {k:v for item in l for k,v in item.items()}
>>> dic
{1: {'item1': 'value1'}, 2: {'item2': 'value2'}}
>>>
Your ordering of the statements is wrong. Think of it in the way that you would order it in a normal loop. So, for item in l comes first and then for k, v in item.items().
>>> dic = dict(((k,v)) for item in l for k,v in item.items())
>>> dic
{1: {'item1': 'value1'}, 2: {'item2': 'value2'}}
Now, the comprehension becomes
for item in l:
for k, v in item.items():
# Do Something
instead of
for k, v in item.items():
for item in l:
# Do Something
which is an error.
list comprehension for's are interpreted just like a normal for loop(which actually is somewhat counter intuitive) so what you have is
for k,v in item.items():
for item in mylist:
k,v
surely you can see the problem with that
first refer to ques How to create single Python dict from a list of dicts by summing values with common keys?
It will help you to analyse your problem.....now thhink of normal loops...
>>> dic = dict(((k,v)) for item in l for k,v in item.items())
>>> dic
{1: {'item1': 'value1'}, 2: {'item2': 'value2'}}
then handled as....
for item in l:
for k, v in item.items():

python dictionary with repetition of key and value

I have two array as follows:
a=['history','math','history','sport','math']
b=['literature','math','history','history','math']
I zipped two arrays and used dictionary to see if key and values are equal print me them but the dictionary did not print the cases which are repeated, it print only one one them and i need all of them because I need the number of time they are repeated.
My code:
combined_dict={}
for k , v in zip(a,b):
combined_dict[k]=v
print(combined_dict)
In dictionaries, there are no duplicate keys. So when you have {'history':'literature'} after the first loop, it will get overriden with {'history':'history'}.
Instead of creating a dictionary, why not just loop through the zip(a, b)?
for k, v in zip(a, b):
if k == v:
print(k, v)
If you want to have multiple values for one key, then you can use a defaultdict from the collections module:
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for k, v in zip(a, b):
... d[k].append(v)
...
>>> print(d)
defaultdict(<type 'list'>, {'sport': ['history'], 'math': ['math', 'math'], 'history': ['literature', 'history']})
>>> print(list(d.items()))
[('sport', ['history']), ('math', ['math', 'math']), ('history', ['literature', 'history'])]
>>> for k, v in d.items():
... if k in v:
... print k, v
...
math ['math', 'math']
history ['literature', 'history']
A dict cannot have the same key for two entries. For multiple values with same key, you need a dict with a list as value.
Try this:
from collections import defaultdict
a=['history','math','history','sport','math']
b=['literature','math','history','history','math']
combined_dict = defaultdict(list)
for k, v in zip(a,b):
combined_dict[k].append(v)
print combined_dict
If you want to get a list of all the items, where there is a match between the two lists, try
>>> print [k for k, v in zip(a, b) if k == v]
['math', 'history', 'math']
This gives you a list of matching items, which you can then process further.

Swap keys for values in dictionary with multiple duplicate values in Python 3

I know how to swap keys and values in a dictionary, but I don't know what I should do if I want to make a set as a value for those multiple keys that correspond with that value.
I have the following code:
def bind(dict1):
dict2 = {}
for k, v in dict1.items():
dict2[v] = {k}
return dict2
The problem is, if I enter for instance
bind({'Europa': 'Jupiter', 'Psamathe': 'Neptune', 'Cordelia': 'Uranus', 'Cupid': 'Uranus'})
It would return the following:
{'Jupiter': {'Europa'}, 'Neptune': {'Psamathe'}, 'Uranus': {'Cupid'}}
while I need to have:
{'Jupiter': {'Europa'}, 'Neptune': {'Psamathe'}, 'Uranus': {'Cupid', 'Cordelia'}}
I have tried to make empty sets as values for my new dictionary by entering:
def bind(dict1):
dict2 = {}
for k, v in dict1.items():
dict2[v] = {}
return dict2
But how can I add values to the corresponding sets belonging to the key dict2[v]?
You could use a defaultdict.
from collections import defaultdict
swapped = defaultdict(set)
for k, v in source.iteritems():
swapped[v].add(k)
defaultdict transparently creates a value at any as-yet-unaccessed key using the callable provided as the initialization argument as a factory. The above is basically equivalent to:
swapped = {}
for k, v in source.iteritems():
if v not in swapped:
swapped[v] = set()
swapped[v].add(k)
>>> import collections
>>> out = collections.defaultdict(set)
>>> inval = {'Europa': 'Jupiter', 'Psamathe': 'Neptune', 'Cordelia': 'Uranus', 'Cupid': 'Uranus'}
>>> for k, v in inval.items():
... out[v].add(k)
...
>>> out
defaultdict(<type 'set'>, {'Jupiter': set(['Europa']), 'Neptune': set(['Psamathe']), 'Uranus': set(['Cordelia', 'Cupid'])})
import collections
def bind(dict1):
dict2 = collections.defaultdict(set)
for k, v in dict1.items():
dict2[v].add(k)
return dict2
result = bind({'Europa': 'Jupiter', 'Psamathe': 'Neptune', 'Cordelia': 'Uranus', 'Cupid': 'Uranus'})
print(result)
yields
defaultdict(, {'Jupiter': set(['Europa']), 'Neptune':
set(['Psamathe']), 'Uranus': set(['Cordelia', 'Cupid'])})
Alternative, you could let dict2 be a dict instead of a collections.defaultdict(set), and use the setdefault method:
def bind(dict1):
dict2 = {}
for k, v in dict1.items():
dict2.setdefault(v,set()).add(k)
return dict2
References:
set.add
collection.defaultdict
dict.setdefault

Categories

Resources