Martin v. Löwis wrote: > Rhamphoryncus schrieb: > > setapproach = """\ > > def func(count): > > from random import random > > items = [random() for i in xrange(count)] > > remove = set() > > for index, x in enumerate(items): > > #...do something... > > if x < 0.5: > > remove.add(index) > > items = [x for index, x in enumerate(items) if index not in remove] > > """ > > This is different from the other approaches in that it doesn't > modify items. If you wanted a new list, you could incrementally > build one already in the first pass, no need to collect the > indices first (as BlackJack explains).
I didn't feel this distinction was worth mentioning, since "oldlist[:] = newlist" is so trivial. The only solution that really avoids making a copy is the reverse-iteration one. > If you wanted in-place modification, I'd do > > newitems = [] > for x in items: > if not (x < 0.5): > newitems.append(x) > items[:] = newitems I agree, that does seem simpler. > > copyapproach = """\ > > def func(count): > > from random import random > > items = [random() for i in xrange(count)] > > for x in items[:]: > > if x < 0.5: > > items.remove(x) > > """ > > This happens to work for your example, but is incorrect > in the general case: you meant to write > > del items[i+removed] > > here, as .remove(x) will search the list again, looking > for the first value to remove. If your condition for > removal happens to leave some items equal to x in the > list, it would remove the wrong item. Because the numbering > changes while the iteration is in progress, you have > to count the number of removed items also. I agree that the example I gave here sucks. However, I copied it from another posting as a recommended method to get removal to work *right* (without noticing how slow it is). There seems to have been many distinct approaches to this problem over the years. Hopefully we can converge on a single ideal solution (or a few situational ones) as TOOWTDI. -- Adam Olsen, aka Rhamphoryncus
-- http://mail.python.org/mailman/listinfo/python-list