Python: finding keys with unique values in a dictionary?

前端 未结 9 2038
臣服心动
臣服心动 2021-02-19 01:28

I receive a dictionary as input, and want to return a list of keys for which the dictionary values are unique in the scope of that dictionary.

I will clarify with an exa

相关标签:
9条回答
  • 2021-02-19 01:30

    Here's another variation.

    >>> import collections
    >>> inverse= collections.defaultdict(list)
    >>> for k,v in a.items():
    ...     inverse[v].append(k)
    ... 
    >>> [ v[0] for v in inverse.values() if len(v) == 1 ]
    ['dog', 'snake']
    

    I'm partial to this because the inverted dictionary is such a common design pattern.

    0 讨论(0)
  • 2021-02-19 01:31

    Use nested list comprehensions!

    print [v[0] for v in 
               dict([(v, [k for k in a.keys() if a[k] == v])
                         for v in set(a.values())]).values()
           if len(v) == 1]
    
    0 讨论(0)
  • 2021-02-19 01:35

    What about subclassing?

    class UniqueValuesDict(dict):
    
        def __init__(self, *args):
            dict.__init__(self, *args)
            self._inverse = {}
    
        def __setitem__(self, key, value):
            if value in self.values():
                if value in self._inverse:
                    del self._inverse[value]
            else:
                self._inverse[value] = key
            dict.__setitem__(self, key, value)
    
        def unique_values(self):
            return self._inverse.values()
    
    a = UniqueValuesDict()
    
    a['cat'] =      1
    a['fish'] =     1
    a[None] =       1
    a['duck'] =     1
    a['dog'] =      2  # <-- unique
    a['bat'] =      3
    a['aardvark'] = 3
    a['snake'] =    4  # <-- unique
    a['wallaby'] =  5
    a['badger'] =   5
    
    assert a.unique_values() == ['dog', 'snake']
    
    0 讨论(0)
  • 2021-02-19 01:38

    A little more verbose, but does need only one pass over a:

    revDict = {}
    for k, v in a.iteritems():
      if v in revDict:
         revDict[v] = None
      else:
         revDict[v] = k
    
    [ x for x in revDict.itervalues() if x != None ]
    

    ( I hope it works, since I can't test it here )

    0 讨论(0)
  • 2021-02-19 01:44

    I think efficient way if dict is too large would be

    countMap = {}
    for v in a.itervalues():
        countMap[v] = countMap.get(v,0) + 1
    uni = [ k for k, v in a.iteritems() if countMap[v] == 1]
    
    0 讨论(0)
  • 2021-02-19 01:45

    You could do something like this (just count the number of occurrences for each value):

    def unique(a):
        from collections import defaultdict
        count = defaultdict(lambda: 0)
        for k, v in a.iteritems():
            count[v] += 1
        for v, c in count.iteritems():
            if c <= 1:
                yield v
    
    0 讨论(0)
提交回复
热议问题