user1529696
user1529696

Reputation: 13

Python: Weird for loop behavior

I'm trying to solve this: CodeEval.

The problem requires me to go through a list of possible candidates of points in a XY-coordinates. Then if they fulfill the requirements I add them to a "confirmed" list and then add the surrounding points to a "tosearch" list. However this does not behave at all the way I expect it to behave.

Example code:

Starting point
tosearch=[[0,0]] 

for point in tosearch:

    if conditions filled:
        confirmed.append(point)
        #Basically Im trying to add (x,y-1) etc. to the tosearct list
        tosearch.append([point[0],point[1]-1])  #1 
        tosearch.append([point[0]+1,point[1]])  #2
        tosearch.append([point[0]-1,point[1]-1])#3
        tosearch.append([point[0],point[1]+1])  #4
        tosearch.remove(point)
else:
     tosearch.remove(point)

This seems to result in always ignoring half of the appends. So in this case #1 and #3 are being ignored. If I left only 1&2 then only 2 would execute. I dont get it...

Maybe the problem is else where so here is the whole code: Pastebin

Upvotes: 1

Views: 320

Answers (2)

Francis Avila
Francis Avila

Reputation: 31621

The problem is you are modifying tosearch in the body of the loop that iterates tosearch. Since tosearch is changing, it can't be iterated reliably.

You probably don't need to iterate at all. Just use a while loop:

searched = set() # if you need to keep track of searched items
tosearch = [(0,0)] #use tuples so you can put them in a set
confirmed = []

while tosearch:
    point = tosearch.pop()
    searched.add(point) # if you need to keep track
    if CONDITIONS_MET:
        confirmed.append(point)
        # tosearch.append() ....

Upvotes: 0

Matthew Vines
Matthew Vines

Reputation: 27561

You're modifying the collection while iterating over it.
2 options:

  1. copy the list, iterate the copy, and alter the original.
  2. keep track of what changes need to be made, and make them all at after iterating.

Upvotes: 5

Related Questions