Why don't people like lisp?
Alex Martelli
aleax at aleax.it
Sun Oct 19 18:27:43 EDT 2003
Paul Rubin wrote:
...
> This is untested but looks simpler than the lisp example:
>
> def mostn (fn, lst):
> max = None
> for a in lst:
> score = fn(lst)
Perhaps "score = fn(a)" ?
> if max is None or score > max:
> max = score
> ret = [a]
> elif score == max:
> ret.append(a)
> return ret
it it all right to raise an exception if lst is empty?
I'm not sure of the lisp example's behavior in that case,
but I suspect it returns an empty list and None. In
that case, we may need to initialize ret to [] too.
Stylistically (but it's just me) I don't much like that
"first-time switch" use -- null in lisp, None in Python.
An alternative might be to treat the empty lst as
an exceptional case:
def mostfn(fn, lst):
try: a = lst[0]
except IndexError: return [], None
ret, max = [], fn(a)
for a in lst:
score = fn(a)
if score > max:
max = score
ret = [a]
elif score == max:
ret.append(a)
return ret, max
a _bit_ more complicated than Paul's code, and calls
fn twice on lst[0], but it caters to my dislike for
"first-time switches"...;-). One could remove the
double-call problem by changing the start to:
def mostfn(fn, lst):
it = iter(lst)
try: a = it,next()
except StopIteration: return [], None
ret, max = [a], fn(a)
for a in it:
...
If taking O(N) auxiliary memory was acceptable, of
course, there would be an alternate possibility:
def mostfn(fn, lst):
if not lst: return [], None
aux = [ (fn(a), a) for a in lst ]
Max = max([ f for f, a in aux ])
return [ a for f, a in aux if f==Max ], Max
Typical problem with all high-level languages --
they often make most attractive an approach that
may not be quite as spare of bytes and cycles as
some lower-level one!-) [A simple test with
fn=lambda x:x%333 and lst=range(9999) shows the
lower-level approach is over 3 times faster,
both with and without psyco.proxy on both].
Alex
More information about the Python-list
mailing list