Let's say I have two set()
s:
a = {('1', '2', '3', 'a'), ('1', '2', '4', 'a'), ('1', '2', '5', 'b')}
b = {('1', '2', '3', 'b'), ('1', '2', '4', 'b'), ('1', '2', '6', 'b')}
Now, what I want to do is to find the set difference b \ a
but ignoring the last element from every tuple. So it's just like doing something like this:
a = {('1', '2', '3'), ('1', '2', '4'), ('1', '2', '5')}
b = {('1', '2', '3'), ('1', '2', '4'), ('1', '2', '6')}
In[1]: b - a
Out[1]: {('1', '2', '6')}
Expected output:
b \ a = {('1', '2', '6', 'b')}
Is there any obvious / pythonic way of achieving this without having to manually iterate over each set and check against each tuple[:3]
?
Get the last element of the list using the “length of list - 1” as an index and print the resultant last element of the list. Get the last element of the list using − 1(negative indexing) as the index and print the resultant last element of the list.
Unlike lists, ordinary sets do not preserve the order in which we insert the elements. This is because the elements in a set are usually not stored in the order in which they appear.
1. Does converting an object to a set maintain the object's order? No. A set is not an ordered data structure, so order is not maintained.
Here's how you might write your own class to override a tuple's normal hashing behaviour:
a_data = [('1', '2', '3', 'a'), ('1', '2', '4', 'a'), ('1', '2', '5', 'b')]
b_data = [('1', '2', '3', 'b'), ('1', '2', '4', 'b'), ('1', '2', '6', 'b')]
class HashableIgnoresLastElement(tuple):
def __eq__(self, other):
return self[:-1] == other[:-1]
def __hash__(self):
return hash(self[:-1])
a = set(map(HashableIgnoresLastElement, a_data))
b = set(map(HashableIgnoresLastElement, b_data))
print(b - a)
with output
{('1', '2', '6', 'b')}
To modify the way sets of tuples behave, we have to modify the way tuples are hashed.
From here,
An object is hashable if it has a hash value which never changes during its lifetime (it needs a
__hash__()
method), and can be compared to other objects (it needs an__eq__()
method). Hashable objects which compare equal must have the same hash value.Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.
So in order to make the hashing ignore the last element, we have to overload the dunder methods __eq__
and __hash__
appropriately. This doesn't end up being so hard because all we have to do is slice off the last element and then delegate to the appropriate methods of a normal tuple
.
Further reading:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With