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 index
th 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
A
set
is an unordered data structure, so it does not preserve the insertion order.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 aset
as well. Note thata.keys() - b.keys()
returns the set difference as aset
, 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
How to (Un)Escape Strings in C/C++
C++ How Is Release-And-Acquire Achieved on X86 Only Using Mov
When to Use Shared_Ptr and When to Use Raw Pointers
How to Detect Ip Address Change Programmatically in Linux
Casting Pointer to Array (Int* to Int[2])
Taking Input of a String Word by Word
Refreshing the Auto Complete (Intellisense) Database in Visual Studio
Is There Any Standard Way of Embedding Resources into Linux Executable Image
Xcode with Boost:Linker(Id) Warning About Visibility Settings
How to Have Two Functions That Call Each Other C++
Visual C++ 2008 Express Download Link Dead
Heap Corruption Under Win32; How to Locate
Is There Any Alternative to Using % (Modulus) in C/C++
Do Child Threads Exit When the Parent Thread Terminates