John J. Lee wrote:
Steve Holden <[EMAIL PROTECTED]> writes: [...]
You are modifying the list as you iterate over it. Instead, iterate over a copy by using:
for ip in ips[:]: ...
Just to help popularise the alternative idiom, which IMO is significantly less cryptic (sane constructors of mutable objects almost always make a copy, and list is no exception: it's guaranteed to do so):
for ip in list(ips): ...
Works back to at least Python 1.5.2.
I don't know that that approach is less cryptic. ips is already a list... it looks cryptic to make it a list again, doesn't it? IMO, the two are equally cryptic. The epitome of clarity would be copy(ips)... now *that* makes sense, of course, ips[:] or list(ips) work equally well to the programmer who has learned them.
This probably seems cryptic until you realize that almost all builtin mutable objects work this way:
py> def copy(obj): ... return type(obj)(obj) ...
py> lst = range(5) py> copy(lst) [0, 1, 2, 3, 4] py> lst is copy(lst) False
py> dct = dict(a=1, b=2) py> copy(dct) {'a': 1, 'b': 2} py> dct is copy(dct) False
py> st = set(range(5)) py> copy(st) set([0, 1, 2, 3, 4]) py> st is copy(st) False
py> from collections import deque py> dq = deque(range(5)) py> copy(dq) deque([0, 1, 2, 3, 4]) py> dq is copy(dq) False
If you're uncomfortable with this form, I'd suggest spending some time playing around with it -- Python is pretty consistent about this usage of a builtin type.
Steve -- http://mail.python.org/mailman/listinfo/python-list