A set has the same question as dictionary keys, as I explained in your another issue - there is no atomic operation to exchange an element.
In this case, you really need to call two methods: one to remove the old value (the method remove
) and another call to add a new element (method add
)
Do a function to do this, and if necessary, as in the other case, you can sophisticated the code in the future to avoid conflicts, put some guarantee for multi-threading, etc:
def troca_elemento(conjunto, antigo, novo):
conjunto.remove(antigo)
conjunto.add(novo)
(As in the case of dictionaries, you may or may not create a new class and leave it as a method - but a function will work equally well).
As I completed in the other answer, if there is an absolute need for this operation to be atomic, that is: there is no risk of code in another thread "seeing" the set in an inconsistent state that is - either with the two values, or without either - the only way to do this is to create another class that responds as a set, and has a thread. Lock in the instance to block access while the change is in progress. For this, the easiest way is to inherit this class of collections.abc.MutableSet
and check the lock on the implemented methods. (In this case, the exchange should be implemented as a class method as well).
It may sound complicated, but it’s simple (the code gets big, but it’s the same strategy in each of the mandatory methods):
from collections.abc import MutableSet
from threading import Lock
class AtomicSet(MutableSet):
def __init__(self, *args, **kw):
self.lock = Lock()
self._data = set(*args, **kw)
def exchange(self, old_value, new_value):
with self.lock:
self._data.remove(old_value)
self._data.add(new_value)
def __contains__(self, value):
with lock:
return value in self._data
def __iter__(self):
with lock:
yield from iterself._data
def __len__(self):
with lock:
return len(self._data)
def add(self, value):
with lock:
self._data.add(value)
def discard(self, value):
with lock:
self._data.discard(value)
def __repr__(self):
return f"Atomic{self._data!r}"
Do you really need to work with sets? If you want you can turn into list, edit and "retransform" into set.
– Breno
As I recall, sets are like sets (which follow the logic of Venn diagrams)
– Breno
sets avoid repetition of objects showing them without any kind of order
– user141036
Exactly, but what would be your specific case?
– Breno
Update element France for Germany
– user141036