How to Modify List Entries During For Loop

How to modify list entries during for loop?

It's considered poor form. Use a list comprehension instead, with slice assignment if you need to retain existing references to the list.

a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print(b)

Modify a list while iterating

You are not modifying the list, so to speak. You are simply modifying the elements in the list. I don't believe this is a problem.

To answer your second question, both ways are indeed allowed (as you know, since you ran the code), but it would depend on the situation. Are the contents mutable or immutable?

For example, if you want to add one to every element in a list of integers, this would not work:

>>> x = [1, 2, 3, 4, 5]
>>> for i in x:
... i += 1
...
>>> x
[1, 2, 3, 4, 5]

Indeed, ints are immutable objects. Instead, you'd need to iterate over the indices and change the element at each index, like this:

>>> for i in range(len(x)):
... x[i] += 1
...
>>> x
[2, 3, 4, 5, 6]

If your items are mutable, then the first method (of directly iterating over the elements rather than the indices) is more efficient without a doubt, because the extra step of indexing is an overhead that can be avoided since those elements are mutable.

C# Modify List item while in a foreach loop

As I can see, you have emails in the friendsOnline:

string[] friendsOnline = new[] {
"Me@Shire.com",
"Dark.Lord@Mordor.gov",
};

and you want to change these emails into names:

string[] friendsOnline = new[] {
"Frodo Baggins",
"Sauron the Black",
};

First of all, I suggest executing query just once: SQL is too slow to be run in a loop; instead you can build a dictionary which eMail corresponds to which indexes:

using System.Linq;

...

// eMail - indexes correspondence
Dictionary<string, int[]> dict = friendsOnline
.Select((name, index) => (name : name, index : index))
.GroupBy(pair => pair.name, pair => pair.index, StringComparer.OrdinalIgnoreCase)
.ToDictionary(group => group.Key, group => group.ToArray());

// We take all users (no WHERE), but once
// We read both username and email
string sql =
@"SELECT `username`,
`email`
FROM `accounts`";

//DONE: using - we should Dispose IDisposable Command and Reader
using cmd = new MySqlCommand(sql, conn);
using rdr = cmd.ExecuteReader();

while (rdr.Read()) {
string name = Convert.ToString(rdr[0]);
string mail = Convert.ToString(rdr[1]);

// If we have correspondent indexes, we change friendsOnline
if (dict.TryGetValue(mail, out var indexes))
foreach (var index in indexes)
friendsOnline[index] = name;
}

How to modify elements of a list as I iterate through them in Kotlin (Val cannot be reasigned)?

First of all, when iterating over a collection, we don't receive some kind of a pointer to the current item. item in your example is only a copy of the current item and modifying it would not affect the list. This is one reason why item is read-only - otherwise it would be misleading as developers would think they modified the list, but in fact they would not. In order to replace the current item we have to either use ListIterator.set() or access the item using its index.

Secondly, it would be tricky to add new items at the end while iterating over the same collection. It is much easier to just remember the number of 0 items and add 10 items after we finish iterating.

Solution using ListIterator.set():

fun listCalculator(myList: MutableList<Int>, number: Int) {
for (i in 0..number) {
var counter = 0
val iterator = myList.listIterator()
for (item in iterator) {
iterator.set(item - 1)

if (item == 1) {
counter++
}
}

repeat(counter) { myList += 10 }
}
}

Solution where we iterate over indices and access the current item manually:

fun listCalculator(myList: MutableList<Int>, number: Int) {
for (i in 0..number) {
var counter = 0
for (index in myList.indices) {
val item = --myList[index]

if (item == 0) {
counter++
}
}

repeat(counter) { myList += 10 }
}
}

Also note that the outer loop does not run number times, but number + 1 times. If you intended to execute it number times, then you have to use for (i in 0 until number) { ... } or just: repeat(number) { ... }

Can't modify list elements in a loop

Because the way for i in li works is something like this:

for idx in range(len(li)):
i = li[idx]
i = 'foo'

So if you assign anything to i, it won't affect li[idx].

The solution is either what you have proposed, or looping through the indices:

for idx in range(len(li)):
li[idx] = 'foo'

or use enumerate:

for idx, item in enumerate(li):
li[idx] = 'foo'

How to change values in a list while using for loop in Python? (without using index)

Python unlike many other languages is dynamically typed as in you don't need to initialize prepopulated arrays(lists) before populating them with data. Also a standard convention is list comprehensions which in lamens are in-line loops that return a list.

a = [1,2,3,4,5]
b = [num * 4 for num in a]

This is equivilent to:

a = [1,2,3,4,5]
b = []
for num in a:
b.append(num * 4)

Modify list values in a for loop

It's not because of the np.clip function. It's because you use loop on a list of mutable, so the value of the element can be modified. You can see here Immutable vs Mutable types for more information.

Modifying list while iterating

I've been bitten before by (someone else's) "clever" code that tries to modify a list while iterating over it. I resolved that I would never do it under any circumstance.

You can use the slice operator mylist[::3] to skip across to every third item in your list.

mylist = [i for i in range(100)]
for i in mylist[::3]:
print(i)

Other points about my example relate to new syntax in python 3.0.

  • I use a list comprehension to define mylist because it works in Python 3.0 (see below)
  • print is a function in python 3.0

Python 3.0 range() now behaves like xrange() used to behave, except it works with values of arbitrary size. The latter no longer exists.



Related Topics



Leave a reply



Submit