[Tutor] filtering within a function.
Michael P. Reilly
arcege@shore.net
Mon, 12 Mar 2001 15:51:22 -0500 (EST)
> On 12 Mar 2001, Michael P. Reilly replied:
> > That is probably because unstray relies on
> > side-effects of the function parameter, which
> > is usually a bad design choice (but not always).
> > Here the problem is that unstray returns nothing
> > and modifies listinput.
>
> In this case, returning nothing and modifying the
> list was a conscious choice, not just how I got
> it to work--no need to retain the original list.
>
> unstray is a crock for the same reason as:
>
> foo = [1, 2, 1, 3, 1, 4]
> for x in foo:
> if x >= 2:
> foo.remove(x)
>
> That looks like it works, but foo[1] is removed,
> foo[2] falls into foo[1], placing it behind the
> iteration, as foo = [1, 2, 3, 4] would reveal.
Yup, if you're going to do this, then it is generally better to use
indices, which just makes life more interesting. ;) The remove()
method removes the first element that matches.
>>> i = 0
>>> while i < len(foo):
... if foo[i] >= 2:
... del foo[i] # do NOT increment i
... else:
... i = i + 1
>>>
> > What you can do is overwrite the list's elements.
> >
> > How about:
> > uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
> > def unstray(listinput, f=lambda x: x in uppercase):
> > l = filter(f, listinput)
> > # replace the contents of listinput with the result of the filtering
> > listinput[:] = l
> >
> > But then, maybe I'm missing the point. :)
>
> Not that I can see. Is this bad form?:
>
> def unstray(listinput):
> f=lambda x: x in uppercase
> l = filter(f, listinput)
> listinput[:] = l
About the only thing is that putting the lambda in the function
declaration does not recreate the lambda function every time and also
keeps it out of the global namespace.
-Arcege
--
------------------------------------------------------------------------
| Michael P. Reilly, Release Manager | Email: arcege@shore.net |
| Salem, Mass. USA 01970 | |
------------------------------------------------------------------------