Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify a list while iterating

I know you should not add/remove items while iterating over a list. But can I modify an item in a list I'm iterating over if I do not change the list length?

class Car(object):
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return type(self).__name__ + "_" + self.name

my_cars = [Car("Ferrari"), Car("Mercedes"), Car("BMW")]
print(my_cars)  # [Car_Ferrari, Car_Mercedes, Car_BMW]
for car in my_cars:
    car.name = "Moskvich"
print(my_cars)  # [Car_Moskvich, Car_Moskvich, Car_Moskvich]

Or should I iterate over the list indices instead? Like that:

for car_id in range(len(my_cars)):
    my_cars[car_id].name = "Moskvich"

The question is: are the both ways above allowed or only the second one is error-free?

If the answer is yes, will the following snippet be valid?

lovely_numbers = [[41, 32, 17], [26, 55]]
for numbers_pair in lovely_numbers:
    numbers_pair.pop()
print(lovely_numbers)  # [[41, 32], [26]]

UPD. I'd like to see the python documentation where it says "these operations are allowed" rather than someone's assumptions.

like image 943
dizcza Avatar asked Jul 01 '17 18:07

dizcza


People also ask

Can I modify list while iterating?

The general rule of thumb is that you don't modify a collection/array/list while iterating over it. Use a secondary list to store the items you want to act upon and execute that logic in a loop after your initial loop.

Can we modify list while iterating in Java?

The Best Answer is At the end the whole list will have the letter "D" as its content. It's not a good idea to use an enhanced for loop in this case, you're not using the iteration variable for anything, and besides you can't modify the list's contents using the iteration variable.

What happens if you modify the value of an element in a list while iterating using iterators?

The size of the List is not being changed, but the object at the index is changing, so technically the List is being modified.

Can we add element in list while iterating?

You can't modify a Collection while iterating over it using an Iterator , except for Iterator. remove() . This will work except when the list starts iteration empty, in which case there will be no previous element. If that's a problem, you'll have to maintain a flag of some sort to indicate this edge case.

How can I modify an array while iterating over it?

The general rule of thumb is that you don't modify a collection/array/list while iterating over it. Use a secondary list to store the items you want to act upon and execute that logic in a loop after your initial loop. Use a while loop that checks for the truthfulness of the array: And it should do it without any errors or funny behaviour.

How do you iterate through a list without muting it?

The general rule of thumb is that you don't modify a collection/array/list while iterating over it. Use a secondary list to store the items you want to act upon and execute that logic in a loop after your initial loop. Try this. It avoids mutating a thing you're iterating across, which is generally a code smell.

What is the use of iterator / list iterator?

? 2. Adding/removing elements to/from List : Iterating using Iterator / ListIterator allows to add / remove element and these modification (add/remove) is reflected in the original List. We will see 2 different examples using Iterator and ListIterator,

Can I modify an element inside a list while traversing it?

There is nothing wrong with the idea of modifying an element inside a list while traversing it (don't modify the list itself, that's not recommended), but it can be better expressed like this: At the end the whole list will have the letter "D" as its content.


2 Answers

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.

like image 156
cs95 Avatar answered Oct 18 '22 04:10

cs95


I know you should not add/remove items while iterating over a list. But can I modify an item in a list I'm iterating over if I do not change the list length?

You're not modifying the list in any way at all. What you are modifying is the elements in the list; That is perfectly fine. As long as you don't directly change the actual list, you're fine.

There's no need to iterate over the indices. In fact, that's unidiomatic. Unless you are actually trying to change the list itself, simply iterate over the list by value.

If the answer is yes, will the following snippet be valid?

lovely_numbers = [[41, 32, 17], [26, 55]]
for numbers_pair in lovely_numbers:
    numbers_pair.pop()
print(lovely_numbers)  # [[41, 32], [26]]

Absolutely. For the exact same reasons as I said above. Your not modifying lovely_numbers itself. Rather, you're only modifying the elements in lovely_numbers.

like image 45
Christian Dean Avatar answered Oct 18 '22 05:10

Christian Dean