identity = lambda x: x -- a Pythonic idiom?
Andrew Dalke
dalke at dalkescientific.com
Sun Nov 18 21:00:15 CET 2001
Marco Antoniotti:
>Within CL, it turns out that `identity' is useful in a number of
>cases, especially when dealing with sequence operators. E.g. the
>`sort' function is really defined as
>
> sort <sequence> <predicate> &key (key #'identity)
>
>So that you can write things like
>
> * (sort '(2 3 4 1) #'<)
> '(1 2 3 4)
> * (sort '((1 3) (3 0) (33 9) (19 5)) #'< :key #'second)
> ((3 0) (1 3) (19 5) (33 9))
>
>All in all a good thing.
I've been staring at this trying to figure out what it does,
and I think I got it. What threw me off, I think, was the
'*'. It's a prompt, and the indented one on the 3rd line is
a misindent -- it should be 7 characters to the left, and there
are actually two different one-line expressions evaluated here.
Then in the "sort <sequence> <predictate> &key (key #'identity)"
line the '&key' says that field is 1) optional and 2) a keyword
argument, and that if not given the identity function is used.
Finally, the "#'" syntax is used to get a reference to a special
symbol, and ':key' is how to specify a keyword argument.
Am I right so far?
Python only uses one function for this, which means the field
extraction and data comparison must be composed into one function,
>>> a = [(1, 3), (3, 0), (33, 9), (19, 5)]
>>> a.sort(lambda x, y: cmp(x[1], y[1]))
>>> a
[(3, 0), (1, 3), (19, 5), (33, 9)]
>>>
The sort function is (was) also defined in terms of C-style
three-way sorting. It's been changed so that only '<' comparison
is needed, but I don't know how that change affects the comparison
function used.
In CL it looks like you'll have to do the same sort of thing
for data values which don't have a 1D sorting, like
>>> a = [(1, 3), (100, 5), (33, 9), (19, 5)]
>>> a.sort(lambda x, y: cmp(x[1], y[1]) or cmp(x[0], y[0]))
>>> a
[(1, 3), (19, 5), (100, 5), (33, 9)]
>>>
Andrew
dalke at dalkescientific.com
More information about the Python-list
mailing list