Questions on Using Python to Teach Data Structures and Algorithms
Bruno Desthuilliers
onurb at xiludom.gro
Thu Sep 28 11:24:54 EDT 2006
Brendon Towle wrote:
> On 28 Sep 2006, at 8:05 AM, python-list-request at python.org wrote:
>
>> From: Bruno Desthuilliers <onurb at xiludom.gro>
>>
>> Brendon Towle wrote:
>>> Some of your Lisp translations are subtly off...
>>
>> Seems correct to me. Lisp lists are linked lists, not arrays.
>>
>>>
>>>> From: "sturlamolden" <sturlamolden at yahoo.no>
>>>>
>>>> If you want to make a chained structure, then perhaps you know LISP?
>>>> This is what the basic machinery of LISP looks like in Python:
>>>>
>>>> def cons(a,b)
>>>> return [a,b]
>>>
>>> should be:
>>> return [a].extend(b)
>>
>> A Lisp cons is made of a reference to it's content and a reference to
>> the rest of the list, so cons = lambda a, b : [a, b] seems the most
>> straightforward translation.
>
> Yes, a lisp cons is a pair of references as you describe. However, the
> following lisp call:
>
> ? (cons <item> <list>)
>
> returns a single level list,
returns a "single level" *Lisp* list - ie, a linked list.
> with <item> as its new first item, and the
> original contents of <list> as the remainder of the list. The OP's code
> doesn't do that; it returns a list of two items, with <list> as the
> second item.
It returns a structure made of a reference to the new item and a
reference to the original list. Which is exactly what Lisp's cons does
AFAIK.
> To put it another way, the following code is always true in Lisp:
>
> ? (= (length (cons <item> <list>)) (1+ (length <list>)))
>
> But the OP's code only allows that to be true when <list> is of length 1.
Not if you're writing the appropriate length function:
def length(linkedlist):
return cdr(linkedlist) and 1 + length(cdr(linkedlist)) or 1
You obviously can't use the Python builtin len() here.
>
> I suppose, of course, that you could claim that the following Lisp list:
>
> (1 2 3 4)
>
> should translate into the following Python list:
>
> [1, [2, [3, [4]]]]
Should actually be
[1, [2, [3, [4, []]]]]
The internal representation of a Lisp list is really (1 (2 (3 (4 ())))),
not (1 2 3 4).
If it's the fact the proposed translation uses Python lists internally
that bother you, you could also implement it with a more heavyweight
solution:
class cons(object):
def __init__(self, car, cdr=None):
self.car = car
self.cdr = cdr
def __repr__(self):
return "<cons %s %s>" % (self.car, self.cdr)
def llist(*args):
alist = None
for item in reversed(args):
alist = cons(item, alist)
print alist
return alist
def cdr(acons):
return acons.cdr
def car(acons):
return acons.car
def length(llist):
if cdr(llist) is None:
return 1
return 1 + length(cdr(llist))
> But, I think that's a bit silly.
It's *of course* a bit silly[1] - Python is not Lisp. But it's a clear
illustration of the difference between Python lists and Lisp lists !-)
[1] OTHO, using this with tuples may be (or may have been) a more
efficient implementation for stacks than plain Python lists, cf Mark
Lutz, "Programming Python", 2nd edition.
>
>>>> def car(structure)
>>>> return structure[0]
>>>>
>>>> def cdr(structure)
>>>> return structure[1]
>>>
>>> should be:
>>> return structure[1:]
>>
>> idem.
>
> I should have pointed out, of course, that the original definition of
> CDR was correct given the original (incorrect) definition of cons.
The original definition of cons() was by no mean "incorrect".
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"
More information about the Python-list
mailing list