I'm looking for a pythonic way to map a given value to a tuple of keys in a data structure, so that datastructure[key1, key2]
returns the same value as datastructure[key2, key1]
, without having to save the value twice for each mutation of the key tuple. Ideally, I'm looking for something like a dictionary with sets or "order-insensitive tuples" (I know, that tuples are by definition ordered) as keys.
My usecase for this is: I need to save similarity values of pairs of strings in an efficient way. Since sim(word1, word2)
equals sim(word2, word1)
(so ordering doesn't matter), I don't want to save the values for each tuple, because it would be redundant. Instead, I'd like to save one value for each word pair (the tuple key) and access it by either ordering of the words that the pair is made up.
Currently, I'm doing it like this and it's working fine:
d = {tuple(sorted(['w1', 'w2'])): 4}
print(d[tuple(sorted(['w1', 'w2']))])
print(d[tuple(sorted(['w2', 'w1']))])
>> 4
>> 4
But each update and access to the dictionary now requires a list initiation, sort action, and tuple transformation.
My question is therefore: Is there an elegant way to do, what I want, without having to use the above workaround or defining a custom class as key? Maybe there is a datastructure that allows exactly that and may even be faster because it is implemented on a lower level than my workaround. Ideally this would look something like this:
d = {('w1', 'w2'): 4}
print(d[('w1','w2')])
print(d[('w2','w1')])
>> 4
>> 4
Note: The above example doesn't work, because ('a2','b2') != ('b2','a2')
.
Here is the research I've done so far and an explanation of why these solutions aren't exactly what I'm looking for:
- Defining a custom Class, where MyObject('a2','b2') equals MyObject('b2','a2') and using these custom objects works fine (Object of custom type as dictionary key) but is more complex than the workaroundabove.
- Using sets, which are by definition position insensitive, as keys yields an error because sets are unhashable.
- The following questions are related but all answers imply saving the same value multiple times for each tuple/key: How to create dict with 2 keys and one value? and Dictionary with multiple keys mapping to same value
I'm thankful for any hints and make excuses in advance, if a duplicate Stackoverflow question exists and I overlooked it - it's hard to search for this, since I don't know how the desired feature would be called.