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.
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.
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.
The size of the List is not being changed, but the object at the index is changing, so technically the List is being modified.
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.
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.
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.
? 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,
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.
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, int
s 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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With