How to update some elements in SET in Python?

Asked

Viewed 168 times

0

Not all the elements I want to update on SET only the country needs to be changed France to Germany

My code is like this:

paises = {'França', 'Japão', 'China', 'Brasil', 'Espanha', 
          'USA', 'China', 'Japão', 'USA', 'Tailândia'}

print (paises)
  • Do you really need to work with sets? If you want you can turn into list, edit and "retransform" into set.

  • As I recall, sets are like sets (which follow the logic of Venn diagrams)

  • sets avoid repetition of objects showing them without any kind of order

  • Exactly, but what would be your specific case?

  • Update element France for Germany

1 answer

4


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}"

Browser other questions tagged

You are not signed in. Login or sign up in order to post.