Reputation: 107
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
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
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
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