Membership check on multiple pairs, how can I make the order of elements in pairs irrelevant?

Here is what I want to do:

m1 = (a,b) m2 = (c,d) bad_combos = set() bad_combos.add((m1,m2)) #((a,b),(c,d)) ... #adding many other elements in the set #when i do this: if (m2,m1) in bad_combos: print("Found") else: print("Not Found") #the result is always "Not Found" 

Is there a way that I can make the order of elements in a pair irrelevant, so when O tests membership:

 bad_combos.add((m3,m4)) if (m4,m3) in bad_combos: #This will return True? 

Any idea would be greatly appreciated! Thanks at Advance!

+5
source share
2 answers

One option (if bad_combos should remain in the set) adds a frozenset to your set, and then checks if the pair hangs:

 m1 = ('a','b') m2 = ('c','d') bad_combos = set() bad_combos.add(frozenset([m1,m2])) (m2, m1) in bad_combos # False frozenset([m2, m1]) in bad_combos # True 

this, of course, retains the complexity of O (1) for membership testing.

Another option (if the set is optional) includes switching to a list as the storage data structure and adding pairs of pairs to it:

 m1 = ('a','b') m2 = ('c','d') bad_combos = [] bad_combos.append({m1,m2}) #((a,b),(c,d)) if {m2,m1} in bad_combos: print("Found") else: print("Not Found") 

this, of course, leads to O (n) membership testing.

+2
source

In general, use set instead of tuple when order does not matter.

However, you cannot add a set to another set. In this case, you can use frozenset :

 m1 = (a, b) m2 = (c, d) # m1 and m2 are tuples bad_combos = set() bad_combos.add(frozenset({m1,m2})) # {m1,m2} is a set # ... if frozenset({m2,m1}) in bad_combos: # True 
+4
source

Source: https://habr.com/ru/post/1271726/


All Articles