Dunno
Dunno

Reputation: 3684

for loop omitting some list elements

What I'm trying to do is to create a circle, and then drop out all the (integer) points in that circle that are out of given bonds (like area intersection of circle and some geometrical figure). The geometrical figure is represented as a list of (x,y) tuples, so is the circle (with additional O variable equal to it's centre). The code I have is:

copy=circle
for bound in bounds:
    for point in circle:
        if checkPointSegmentIntersection(O,point,bound):
            copy.remove(point)
        print bound, point
print copy

The centre of the circle I'm testing now equals (5,8) and the radius equals 3. One of the borderline points of the circle is (5,11), and there's a point in bounds equal to (5,10). So points (5,11) and (5,10) should get removed from copy. (5,10) does, but (5,11) doesn't. What's more, the pair (5,10) (5,11) don't even appear in the output, (5,10) (5,10) does)! The inner loops continues with bound equal (5,10), (5,11) is the only point omitted. (5,11) does appear in other outer loop iterations. What's going on? What can cause the loop to omit one of the points?

A little background: this code executes on a django server, the bounds list is moderately big, it contains 10-15 elements, and I'm using python 2.7. The checkPointSegmentIntersection(A,B,X) function works and returns True if X is on a line segment between A and B. I'm also open to any ideas for different approaches to the general problem at hand.

Thanks!

Upvotes: 2

Views: 292

Answers (2)

sshashank124
sshashank124

Reputation: 32189

Where you think you are creating a copy of the list you are simply creating another reference to the same memory space. Instead, you should use

circ_copy=circle[:]

This essentially takes a copy of the whole of circle and stores it as a new list in circ_copy. Now you can run your loop. Your intentions, however, were perfectly right in trying to iterate through the copy list and make changes to the original list.

Upvotes: 6

dabhaid
dabhaid

Reputation: 3879

It might be clearer to separate things so you have a function

checkPointSegmentIntersection(point, bounds)

that returns True or False for a point against the current bounds.

Then you could do something like

[point for point in circle if checkPointsSegmentIntersection(point, bounds)]

Upvotes: 2

Related Questions