-1

I am trying to write simple code to print an item of a list and remove it after printing:

list = ['a', 'b', 'c']

for i in list:
    print(i)
    list.remove(i)

But output is weird:

a
c

Why is output thay way?

  • Why do you need to remove items one at a time? You can print the whole list, then call `list.clear().` (Modifying a list *while* you iterate over it causes the problem you see: after `a` is removed, `b` is the first element of the list, but then the iterator advances anyway to the second time of the list, which is now `c`.) – chepner Aug 13 '22 at 15:09

3 Answers3

2

When you iterate over a list, you get the items in order of their indices (item 0, item 1, item 2, etc). When you remove an item from a list, the indices of all the items after that shift by one.

In the first iteration, the list is ['a', 'b', 'c'], and i is list[0].

During the first iteration, you remove 'a'.

In the second iteration, the list is ['b', 'c'], and i is list[1]. You get 'c' instead of 'b' because 'c' is now at index 1.

If you want to remove each item as you iterate, the better approach would be to iterate in a while loop as long as the list contains items, and pop as you print:

my_list = ['a', 'b', 'c']
while my_list:
    print(my_list.pop(0))

In many cases, it's better to do the thing you want to do in the iteration, and then clear the list:

for i in my_list:
    print(i)
my_list.clear()
Samwise
  • 68,105
  • 3
  • 30
  • 44
1

You're currently iterating while removing the items, if you want alter the list while reading it then probably you want to use the length "as index":

list = ['a', 'b', 'c']

while len(list):
    # pop does what you want: read the element at index [i] and remove it from the list
    print(list.pop(0))

Output:

a
b
c
Alex Rintt
  • 1,618
  • 1
  • 11
  • 18
0

Explanation

the reason the output seems strange it's because you are removing items when iterating over a list.

the problem here is that python iterates checking for the index.

Consider this example:

lst = [32,43,2]
for x in lst:
    lst.pop(0)
    print(x,lst)

Outputs

32 [43, 2]
2 [2]

here you can see the problem. in the first iteration it took the first item that was removed, all ok. The problem starts with the second iteration.

The iterator thinks the index to go is 1 (2nd element) but it's actually the 1st since the first element was removed.

You can fix it also by iterating the reversed list as the index cannot change.

also see this question for more information


Possible solutions

You should iterate over a copy instead:

for x in mylist.copy():
   mylist.remove(x)

You could also use a while loop and list.pop.

while mylist:
    print(mylist.pop(0)) 

Advice

Before leaving, I would like to give some advice.

  1. Don't use builtin as variable names, it causes confusion and could cause conflict in your code if it uses those builtin names.
  2. I would advice to clear the list after the loop using the list.clear() method.
  3. Use the list.pop method if you want to know a value and remove it at the same time.

Useful links

XxJames07-
  • 1,833
  • 1
  • 4
  • 17