Python and Lisp : car and cdr

Hrvoje Niksic hniksic at xemacs.org
Sun Jun 19 10:26:56 EDT 2011


Ethan Furman <ethan at stoneleaf.us> writes:

>> 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:]' ?

Not for the linked list implementation he presented.

>> def length(L):
>>     if not L: return 0
>>     return 1 + length(cdr(L))
>
> How is this different from regular ol' 'len' ?

len would just return 2 for every linked list, and would raise an
exception for empty list (represented by None in Lie's implementation).

A more Pythonic implementation would represent the linked list as a
first-class objects with car and cdr being attributes, allowing for
fairly natural expression of __len__, __iter__, etc.  For example:

class List(object):
    __slots__ = 'car', 'cdr'

    def __init__(self, it=()):
        it = iter(it)
        try:
            self.car = it.next()
        except StopIteration:
            pass
        else:
            self.cdr = List(it)

    def __len__(self):
        if not hasattr(self, 'cdr'):
            return 0
        return 1 + len(self.cdr)

    def __iter__(self):
        head = self
        while hasattr(head, 'cdr'):
            yield head.car
            head = head.cdr

    def __repr__(self):
        return "%s(%r)" % (type(self).__name__, list(self))

>>> l = List([1, 2, 3])
>>> l
List([1, 2, 3])
>>> l.car
1
>>> l.cdr
List([2, 3])
>>> l.cdr.cdr.car
3
>>> l.cdr.cdr.cdr
List([])
>>> tuple(l)
(1, 2, 3)



More information about the Python-list mailing list