Search code examples
pythondictionaryordereddictionary

slicing dictionary with values


I have a dictionary like:

d = {1: 'a', 2:'b', 3:'c', 4:'c', 5:'c', 6:'c'}

I want to slice this dictionary such that if the values in the end are same, it should return only the first value encountered. so the return is:

d = {1: 'a', 2:'b', 3:'c'}

I'm using collections.defaultdict(OrderedDict) to maintain sorting by the keys.

Currently, I'm using a loop. Is there a pythonic way of doing this?


UPDATE

the dictionary values can also be dictionaries:

d = {1: {'a': 'a1', 'b': 'b1'}, 2:{'a': 'a1', 'b': 'b2'}, 3:{'a': 'a1', 'b': 'c1'}, 4:{'a': 'a1', 'b': 'c1'}, 5:{'a': 'a1', 'b': 'c1'}, 6:{'a': 'a1', 'b': 'c1'}}

output:

d = {1: {'a': 'a1', 'b': 'b1'}, 2:{'a': 'a1', 'b': 'b2'}, 3:{'a': 'a1', 'b': 'c1'}}

Solution

  • You can use itertools.groupy with a list-comprehension to achieve your result

    >>> from itertools import groupby
    
    >>> d = {1: 'a', 2:'b', 3:'c', 4:'c', 5:'c', 6:'c'}
    >>> n = [(min([k[0] for k in list(g)]),k) for k,g in groupby(d.items(),key=lambda x: x[1])]
    >>> n
    >>> [(1, 'a'), (2, 'b'), (3, 'c')]
    

    The above expression can also be written as

     >>> from operator import itemgetter
     >>> n = [(min(map(itemgetter(0), g)), k) for k, g in groupby(d.items(), key=itemgetter(1))]
    

    You can cast this to dict by simply using

    >>> dict(n)
    >>> {1: 'a', 2: 'b', 3: 'c'}
    

    This obviously don't maintain order of keys, so you can use OrderedDict

    >>> OrderedDict(sorted(n))
    >>> OrderedDict([(1, 'a'), (2, 'b'), (3, 'c')])