honj - t
honj - t

Reputation: 107

How to check if list values inside a dictionary are equal?

I have a dictionary which is checked every so often in a loop. The loop should determine if the lists inside the dictionary are all equal. I tried using this function (below) - will print 1 if the values are all equal.

def equalDict(values):
    sample = []
    for i in values:
        for j in i:
            sample.append(str(j))
    
    return (len(set(sample))) 

the values parameter contains somedict.values() and the dictionary contains these key value pairs:

sample = {'w0':[0.2, 0.2, 0.30000000004],'w1': [0.2, 0.2, 0.30000000004],'w2': [0.2, 0.2, 0.30000000004], 'w3': [0.2, 0.2, 0.30000000004]}

while all of these are the same, the function returns 2 instead of 1. Am I doing this correctly?

Upvotes: 0

Views: 2036

Answers (3)

pythonic_love
pythonic_love

Reputation: 73

joseville's solution is very informative and correct. In this situation I use a custom function as:

def compare(self, mydict): 
    for list1 in mydict.values():
        for list2 in mydict.values():
            if not list1 == list2:
                # return false, give warning, break etc.

I loop through dictionary values with respect to a dictionary test value and compare.

Upvotes: 0

ramzeek
ramzeek

Reputation: 2315

Is there a reason you can't just use ==?

>>> a = ["a", 2, 3]
>>> b = ["a", 2, 3]
>>> a == b
True
>>> b = [1,2]
>>> a == b
False

So for your specific case,

sample = {'w0':[0.2, 0.2, 0.30000000004],'w1': [0.2, 0.2, 0.30000000004],'w2': [0.2, 0.2, 0.30000000004], 'w3': [0.2, 0.2, 0.30000000004]}

keys = list(sample.keys())

value = True
for key in keys[1:]:
    if sample[keys[0]]!=sample[key]:
        value = False
        break

print(value)

Upvotes: 3

joseville
joseville

Reputation: 953

Your code, as it is, is not checking that all the lists are equal. It's returning the total count of unique elements across all lists.

With your example:

sample = {'w0':[0.2, 0.2, 0.30000000004],'w1': [0.2, 0.2, 0.30000000004],'w2': [0.2, 0.2, 0.30000000004], 'w3': [0.2, 0.2, 0.30000000004]}

equalDict(sample.values()) computes and returns len({0.2, 0.30000000004}) which is 2.


To check that the elements of a list are all equal, you can do:

all_equal = len(set(elements)) == 1

if and only if each element in elements is hashable/immutable. In this case, elements is a list of list -- i.e. each element is a list -- list's aren't hashable/immutable, so you'd get TypeError: unhashable type: 'list' if you tied:

elements = [[0.2, 0.2, 0.30000000004], [0.2, 0.2, 0.30000000004], [0.2, 0.2, 0.30000000004]]
all_equal = len(set(elements)) == 1 # TypeError: unhashable type: 'list'

One workaround is to turn each element/list into a tuple (tuple's are hashable/immutable):

Case where elements are all equal:

elements = [[0.2, 0.2, 0.30000000004], [0.2, 0.2, 0.30000000004], [0.2, 0.2, 0.30000000004]]
elements = map(tuple, elements)
all_equal = len(set(elements)) == 1
print(all_equal) # True

Case where elements are not all equal

elements = [[0.1, 0.2, 0.30000000004], [0.2, 0.2, 0.30000000004], [0.2, 0.2, 0.30000000004]]
elements = map(tuple, elements)
all_equal = len(set(elements)) == 1
print(all_equal) # False

This will only work if each element in elements is a list of hashable/immutable values, so the following would cause an error:

elements = [[0.1, 0.2, [1, 2]], [0.2, 0.2, [1, 2]], [0.2, 0.2, [1, 2]]]
elements = map(tuple, elements)
all_equal = len(set(elements)) == 1
print(all_equal) # TypeError: unhashable type: 'list'

but that doesn't seem to be your use case.


In summary:

def all_equal(elements):
    elements = map(tuple, elements)
    return len(set(elements)) == 1

will work for your use case where elements is a list of list of hashable/immutable values such as [[0.2, 0.2, 0.30000000004], [0.2, 0.2, 0.30000000004], [0.2, 0.2, 0.30000000004]].

Upvotes: 4

Related Questions