Home > Mobile >  How can this code for calculating a list of all dictionary values that occur only once be improved t
How can this code for calculating a list of all dictionary values that occur only once be improved t

Time:10-26

Given a python dictionary. I've written a function that returns a list of keys whose values are unique in the given dictionary. Let's say that aDict = {1: 1, 3: 2, 6: 0, 7: 0, 8: 4, 10: 0}. The function returns [1, 3, 8]. Keys that are mapped to 0 aren't returned because their share value with other key.

The function works but it's complexity is quadratic and verbose. I couldn't do it with dictionary comprehension.

def foo(aDict):
    result = []
    for key in aDict.keys():
        count = 0
        for other in aDict.keys():
            if aDict[key] == aDict[other]:
                count  = 1
                if count > 1:
                    break
        else:
            result.append(key)
    return sorted(result)


print(foo({1: 1, 3: 2, 6: 0, 7: 0, 8: 4, 10: 0}))

CodePudding user response:

You can do that in linear time like this

from collections import defaultdict

def foo1(aDict):
    capture = defaultdict(lambda: 0)
    for i in aDict:
        capture[aDict[i]]  = 1
    return [k for k in aDict if capture[aDict[k]] < 2]

print(foo1({1: 1, 3: 2, 6: 0, 7: 0, 8: 4, 10: 0}))

CodePudding user response:

One liner should be

from collections import Counter
d = {1: 1, 3: 2, 6: 0, 7: 0, 8: 4, 10: 0}
n_d = Counter(d.values())
[k for k in d if n_d[d[k]]==1]
# [1, 3, 8]

Store the values of dictionary in Counter and then iterate through your dictionary keys and check the count from Counter if count == 1 then reside that in a list. It will work in O(n) time

CodePudding user response:

def foo(aDict):
    vals_to_delete = set()
    els = set()
    res = set()
    for v in aDict.values():
        if v in els:
            vals_to_delete.add(v)
        els.add(v)
    for k,v in aDict.items():
        if v not in vals_to_delete:
            res.add(k)
    return res

print(foo({1: 1, 3: 2, 6: 0, 7: 0, 8: 4, 10: 0})) # {8, 1, 3}

CodePudding user response:

Simply counting the individual value in all values list, if its just once give the key.

Code:

dic =  {1: 1, 3: 2, 6: 0, 7: 0, 8: 4, 10: 0}
[k for k,v in dic.items() if list(d.values()).count(v)==1]]

Output:

[1,3,8]
  • Related