Hash states to be able to compare them

Question:

I have these two states that represent the same state, but with changed order, with Python:

state1 = [ [1,5,6], [8,2,1] ]
state2 = [ [8,2,1], [1,5,6] ]

How can I hash these two states to be able to compare them? (state1 == state2)

Asked By: Sergio

||

Answers:

I would do it like this:

>>> from collections import Counter
>>> def my_hash(state):
...     counter = Counter(map(tuple, state))
...     items = frozenset(counter.items())
...     return hash(items)
... 
>>> my_hash(state1) == my_hash(state2)
True
Answered By: wim

Just to be able to compare them, you don’t need to hash them. For example, sets support unordered comparisons. You just need to make the sublists hashable first, which you can do by converting them to tuples:

def state_comparable(state: list[list[int]]) -> set[tuple[int]]:
    return {tuple(sub) for sub in state}
>>> state_comparable(state1) == state_comparable(state2)
True

But if you do need to hash them, you can simply swap set for frozenset:

def state_hash(state: list[list[int]]) -> int:
    return hash(frozenset(tuple(sub) for sub in state))
>>> state_hash(state1) == state_hash(state2)
True

Note: These solutions assume the sublists are always unique. Otherwise, see wim’s answer for how to use a Counter.

Answered By: wjandrea

the easiest:

sorted(state1) == sorted(state2)

It may be more correct to convert to set, But then the list inside the list needs to be converted to a tuple:

state1 = [ [1,5,6], [8,2,1] ]
state2 = [ [8,2,1], [1,5,6] ]

s1 = set(tuple(i) for i in state1)
s2 = set(tuple(i) for i in state2)

s1 == s2
Answered By: Elicon
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.