Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python list.remove() skips next element in list

Tags:

python

Python, but not programming, newbie here. I'm programming with lists and have run into an interesting problem.

width = 2
height = 2

# Traverse the board
def traverse(x, y):
    # The four possible directions
    squares = [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]
    print squares

    # Remove impossible squares
    for square in squares:
        print "now accessing", square
        if (square[0] < 1 or square[0] > width or 
            square[1] < 1 or square[1] > height or
            square == (1, height)):
            squares.remove(square)
            print "removed", square
    print(squares)

# Testing traverse
traverse(1,1)

This results in the following output:

[(0, 1), (2, 1), (1, 0), (1, 2)]
now accessing (0, 1)
removed (0, 1)
now accessing (1, 0)
removed (1, 0)
[(2, 1), (1, 2)]

It completely skips the elements (2,1) and (1,2) -- without even checking them! I found answers here saying I shouldn't be modifying a list while traversing it, and yup, that definitely makes sense. Rookie mistake. But can someone tell me WHY it doesn't work? What's behind the veil of Python lists?

like image 884
yuechen Avatar asked Jan 10 '13 21:01

yuechen


People also ask

How do you remove an element from a list in Python while iterating?

We can delete multiple elements from a list while iterating, but we need to make sure that we are not invalidating the iterator. So either we need to create a copy of the list for iteration and then delete elements from the original list, or we can use the list comprehension or filter() function to do the same.

How do I get the next element in a list?

The idea is to access the next element while iterating. On reaching the penultimate element, you can access the last element. Use enumerate method to add index or counter to an iterable(list, tuple, etc.). Now using the index+1, we can access the next element while iterating through the list.

What are the two methods for removing items from a list in Python?

In Python, use list methods clear() , pop() , and remove() to remove items (elements) from a list. It is also possible to delete items using del statement by specifying a position or range with an index or slice.


1 Answers

Others have explained that you should not remove elements from an array you are iterating over; however, if you traverse the array backwards, there is no problem.

The most compact way to solve this problem (assuming you don't need a copy of the original array after you are done) is to use the reversed() function, as in

for square in reversed(squares)

This will start iterating from the end of the array, and work backwards. Taking out elements in this way will not affect the rest of the code, since you are not changing the order of elements you have not yet visited. I think this is the most elegant way to solve this. I learnt this trick here

like image 190
Floris Avatar answered Sep 21 '22 08:09

Floris