How to Change a Set Element

How to change a set element?

The elements of the set will be in sorted order. If you are allowed to modify an element, then this sorting order can not be maintained. Hence you can not modify the item. You need to erase the existing element and insert a new one.

How can i replace element in set?

You have got to erase() one element and insert() the new one. replace is not defined for std::set. See http://www.cplusplus.com/reference/set/set/

What are the pythonic way to replace a specific set element?

Sets are unordered, so the 'third' element doesn't really mean anything. This will remove an arbitrary element.

If that is what you want to do, you can simply do:

data.pop()
data.add(new_value)

If you wish to remove an item from the set by value and replace it, you can do:

data.remove(value) #data.discard(value) if you don't care if the item exists.
data.add(new_value)

If you want to keep ordered data, use a list and do:

data[index] = new_value

To show that sets are not ordered:

>>> list({"dog", "cat", "elephant"})
['elephant', 'dog', 'cat']
>>> list({1, 2, 3})
[1, 2, 3]

You can see that it is only a coincidence of CPython's implementation that '3' is the third element of a list made from the set {1, 2, 3}.

Your example code is also deeply flawed in other ways. new_list doesn't exist. At no point is the old element removed from the list, and the act of looping through the list is entirely pointless. Obviously, none of that really matters as the whole concept is flawed.

How do I change the value of an item in a Set?

The only way to "modify" a (primitive) item would be to remove it from the Set and then add the altered item.

const mySet = new Set([]);mySet.add('hello');mySet.add('hewwo');mySet.add('henlo');
if (mySet.has('hello')) { mySet.delete('hello'); mySet.add('hello world');}
console.log(...mySet);

Modifying elements in std::set

Elements of a std::set are const. If you want to mutate the elements you need to do insertions and removals to put the container in the state you want.

In your code example:

for (auto item : s)

gets translated into something like:

for (auto iter = s.begin(); iter != s.end(); ++iter)
{
auto item = *iter; // Copy!
// loop body
}

The loop induction variable item is a copy of the element from the set, not a reference to the actual element in the set. As a result, the set is not changed. To change a set you need to call a member function of set, e.g. insert or erase.

Changing item to &item won't help here; if you do this you'll get a compile-time error because the elements of the set are const, so you can't apply reverse to them.

How to update an existing element of std::set?

Since val is not involved in comparison, it could be declared mutable

struct Foo {
Foo(int i, int j) : id(i), val(j) {}
int id;
mutable int val;
bool operator<(const Foo& other) const {
return id < other.id;
}
};

This implies that the value of val may change in a logically-const Foo, which means that it shouldn't affect other comparison operators etc.

Or you could just remove and insert, that takes O(1) additional time (compared to accessing and modifying) if insertion uses the position just before just after the old one as the hint.

Something like:

bool alreadyThere = !p.second; // you forgot the !
if (alreadyThere)
{
Set::iterator hint = p.first;
hint++;
s.erase(p.first);
s.insert(hint, f);
}

Dart: How to update value in Set

Sets elements only have indices incidentally because they are iterables. You can't "update the value at position x" because any update may change the order.

I assume you do want to keep the iteration order (and in that case, you really should be using a list!), so the following won't work:

 void update<T>(Set<T> elements, int index, T newValue) {
set.remove(set.elementAt(index));
set.add(newValue);
}

The problem here is that you won't preserve iteration order, the new value that you added is likely at the end of the iteration (if you are using an insertion-ordered set), or maybe the order has changed completely (if you are not).

An approach which works for insertion-ordered sets:

void replace<T>(Set<T> set, int index, T newValue) {
if (set.contains(newValue)) throw StateError("New value already in set");
int counter = 0;
while (counter < set.length) {
var element = set.first;
set.remove(element);
if (counter == index) element = newValue;
set.add(element);
counter++;
}
}

This repeatedly removes the first element in the set, then inserts it again, except for the indexth element, where it inserts newValue instead.
This only works for insertion-ordered sets (like the default LinkedHashSet).
(Notice that this will not work if newValue is already in the set, so I made it throw in that case).

For all other sets, there is no better solution that (set.toList()..[index] = newValue).toSet().

update the value in set Python?

You'll have to remove the element from the set, and add a new element with that value updated. That's because sets use hashing to efficiently eliminate duplicates. If mutating the elements directly was allowed you'd break this model.

I think you only want the first element to be unique, and track some data associated with that first element. If so you want to use a dictionary instead; use the first element as a key to map to the other two values, in a list for easy altering:

>>> x = {}
>>> x['A1760ulorenaf0821x151031175821564'] = [1, 0]
>>> x['A1760ulorenaf0821x151031175821564'][1] += 1 # increment the second element.
>>> x
{'A1760ulorenaf0821x151031175821564': [1, 1]}

Keys in a dictionary also must be unique.

Note that set.update() only gives you a union operation; the set is updated in-place by adding all elements from the argument(s) that are not already in the set. set.update() cannot alter elements already in the set, because elements the set should not be altered (or at least not in ways that change their hash and equality).

Converting a list to a set changes element order

  1. A set is an unordered data structure, so it does not preserve the insertion order.

  2. This depends on your requirements. If you have an normal list, and want to remove some set of elements while preserving the order of the list, you can do this with a list comprehension:

    >>> a = [1, 2, 20, 6, 210]
    >>> b = set([6, 20, 1])
    >>> [x for x in a if x not in b]
    [2, 210]

    If you need a data structure that supports both fast membership tests and preservation of insertion order, you can use the keys of a Python dictionary, which starting from Python 3.7 is guaranteed to preserve the insertion order:

    >>> a = dict.fromkeys([1, 2, 20, 6, 210])
    >>> b = dict.fromkeys([6, 20, 1])
    >>> dict.fromkeys(x for x in a if x not in b)
    {2: None, 210: None}

    b doesn't really need to be ordered here – you could use a set as well. Note that a.keys() - b.keys() returns the set difference as a set, so it won't preserve the insertion order.

    In older versions of Python, you can use collections.OrderedDict instead:

    >>> a = collections.OrderedDict.fromkeys([1, 2, 20, 6, 210])
    >>> b = collections.OrderedDict.fromkeys([6, 20, 1])
    >>> collections.OrderedDict.fromkeys(x for x in a if x not in b)
    OrderedDict([(2, None), (210, None)])


Related Topics



Leave a reply



Submit