Python and Lisp : car and cdr
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Sun Jun 19 09:24:39 EDT 2011
On Sun, 19 Jun 2011 05:56:27 -0700, Ethan Furman wrote:
> Lie Ryan wrote:
>> On 06/18/11 00:45, Franck Ditter wrote:
>>> Hi, I'm just wondering about the complexity of some Python operations
>>> to mimic Lisp car and cdr in Python...
>>>
>>> def length(L) :
>>> if not L : return 0
>>> return 1 + length(L[1:])
>>>
>>> Should I think of the slice L[1:] as (cdr L) ? I mean, is the slice a
>>> copy of a segment of L, or do I actually get a pointer to something
>>> inside L ? Is the above function length O(n) or probably O(n^2) ?
>>> Where are such implementation things (well) said ?
>>>
>>> Thanks,
>>>
>>> franck
>>
>> Your function does not mimic Lisp's car/cdr. This one does:
>>
>>
>> def car(L):
>> return L[0]
>> def cdr(L):
>> return L[1]
>
> IANAL (I am not a Lisper), but shouldn't that be 'return L[1:]' ?
No. Each cell in a Lisp-style linked list has exactly two elements, and
in Python are usually implemented as nested tuples:
(head, tail) # Annoyingly, this is also known as (car, cdr).
where head is the data value and tail is either another Lisp-style list
or a marker for empty (such as the empty tuple () or None).
So a one-element linked list might be given as:
(42, None)
A two element list: (42, (43, None))
Three element list: (42, (43, (44, None)))
and so forth. So while you could harmlessly use a slice L[1:], there is
no point, since L[1:] will have at most a single element.
>> def length(L):
>> if not L: return 0
>> return 1 + length(cdr(L))
>
> How is this different from regular ol' 'len' ?
The point is to duplicate Lisp's implementation, not to be useful :)
Regular len will return 2, no matter how many elements you have in the
linked list, because it doesn't look at the tail recursively.
--
Steven
More information about the Python-list
mailing list