Hi,
I’m kind of lost with the following code.
I write a for loop as follows:
list = [1, 30, 25, 60, 27, 28]
for item in list:
if item < 29:
list.remove(item)
print(list)
the output I get is:
[30, 60, 28]
Why is ‘28’ still in the list?
Hi,
I’m kind of lost with the following code.
I write a for loop as follows:
list = [1, 30, 25, 60, 27, 28]
for item in list:
if item < 29:
list.remove(item)
print(list)
the output I get is:
[30, 60, 28]
Why is ‘28’ still in the list?
FYI when posting code please format it using the pre-formatted text option.
Select the code and click the </>
button.
You are modifing the list as you interate over it. Which means it will be skipping items.
Your code with two changes:
I changed list
to values
as list is a built in python type.
There is a print in the loop to show what is happening.
values = [1, 30, 25, 60, 27, 28]
for item in values:
print(f'item is {item}')
if item < 29:
values.remove(item)
print(values)
And here is how it runs. Notice what the item is each time around the loop.
python3 loop.py
item is 1
item is 25
item is 27
[30, 60, 28]
You could make a new list with the values you want like this:
values = [1, 30, 25, 60, 27, 28]
new_values = []
for item in values:
if item >= 29:
new_values.append(item)
print(new_values)
Or using a list comprehension like this:
values = [1, 30, 25, 60, 27, 28]
new_values = [value for value in values if value >= 29]
print(new_values)
Thanks so much for your quick answer and your hint how to post code, I’m new here …
Anyway, I figured out on my own that I have to create an additional list, the hint with the comprehension is above my knowledge of python, but I understand it. Thanks
What I don’t understand concerning the logic of python, why the loop stops at the item one before the last and doesn’t proceed also the last item in the list …
The for gets an iterator for the list.
The iterator will return each item in sequence only if the list is not changed.
Because you delete items from the list the iterator loses its place and skips over items.
The rule is do not change a list when iterating over it.
To clarify the answer above, when a for loop iterates over a list it will get the first element, second element, …, n-th element, …, last element. That is, it gets the item in each position of the list until there are no more items. If you remove elements, you change the position of any subsequent element, so they may be skipped.
So the original example, step-by-step, becomes:
Note that if your original list was [1, 30, 25, 10, 27, 28], in the end it would be [30, 10, 28]. Do you understand why? What would the result be if you started with [1, 10, 25, 60, 27, 28]? And with [1, 30, 60, 25, 27, 28]? Try it out!
Or at the very least, if you have/need to (for some reason), iterate over the list backwards, so that any element shifting takes place for the items you’ve already gone through.
for item in values[::-1]:
You are making a copy of the list right?
The original list can be changed as it’s not the base for the iterator that is using the copy of the list.
Thanks Barry, that makes sense
Thanks Tiago, that is a great explanation!