[Python-ideas] Where-statement (Proposal for function expressions)
Steven D'Aprano
steve at pearwood.info
Sun Jul 19 04:08:57 CEST 2009
On Sun, 19 Jul 2009 06:11:57 am Gerald Britton wrote:
> > items.sort(key=compute_sort_value) where:
> >> Now, the body of compute_sort_value appears exactly where it is
> >> executed: within the call to items.sort().
> >
> > No it doesn't. The function definition appears outside the call to
> > sort(). For the function definition to appear inside the call to
> > sort, you'd need to write something like
>
> Yes, it does appear within the call. The call is more than just the
> parameters in parentheses. It begins with "items.sort" and ends (in
> this case) with then end of the "where" clause
That's a definition of "within" that I'm not really happy with. And I
think it's wrong. Consider the timing of calls:
import time
class MyList(list):
def sort(self, *args, **kwargs):
print "Call to sort() started at %s seconds" % time.time()
super(MyList, self).sort(*args, **kwargs)
print "Call to sort() ended at %s seconds" % time.time()
items = MyList([-9, 7, -4, 2, -1, 0, 3])
items.sort(key=func) where:
print "Enter the where-block at %s seconds" % time.time()
time.sleep(555)
def func(item):
return abs(item)
You need to create func before you can pass it as an argument to sort(),
so I would expect the above to print something like:
Enter the where-block at 1234560000.23 seconds
Call to sort() started at 1234560555.24 seconds
Call to sort() ended at 1234560555.25 seconds
To my mind, to say that the contents of the where-block occur "within"
the call to sort, it would imply that you get output like this:
Call to sort() started at 1234560000.23 seconds
Enter the where-block at 1234560000.24 seconds
Call to sort() ended at 1234560555.25 seconds
> > items.sort(key=lambda item: value)
>
> The idea behind "where" clauses is not to replace lambdas. In fact,
> they are useful together:
>
> items.sort(key=mysort) where:
> mysort = sort_key_function_factory(
> with, many, arguments)
If you're going to say that where and lambda are useful together,
shouldn't your example actually show where and lambda together?
> which to many is preferable over:
>
> items.sort(key=lambda item:sort_key_function_factory(with, many,
> arguments))
That's equivalent to:
def f(item):
function = sort_key_function_factory(with, many, arguments)
return function
items.sort(key=f)
which almost certainly is not what you what.
I think what you meant was:
items.sort(key=lambda item:
sort_key_function_factory(with, many, arguments)(item)
) # note that you call the function returned by the factory
which at least works, but it adds a pointless layer of indirection. What
you should have is:
items.sort(key=sort_key_function_factory(with, many, arguments))
which of course is simpler than your earlier example with the
where-block.
--
Steven D'Aprano
More information about the Python-ideas
mailing list