[Tutor] Still on Linked Lists [References, UserDict]
Daniel Yoo
dyoo@hkn.eecs.berkeley.edu
Wed, 4 Apr 2001 00:26:36 -0700 (PDT)
On Tue, 3 Apr 2001, VanL wrote:
> I know that all of you are probably going to groan, but I really don't
> have any special affection for linked lists. I am just trying to use
> them as a tool to learn stuff.
No prob, don't worry about it.
> That said, I have two questions. I will raise one in this email and the
> other in the next.
>
> 1. I put together a new implementation of a linked list class:
>
> class LinkedList2:
>
> """ This class provides a generic node for linked lists. Other
> python classes or
> objects can inherit from this class to get the ability to represent
> themselves as
> a linked list. """
>
> def __init__(self, name, data=None, object=None):
> self = (name, data, object)
There's something here that you'll need to fix; unfortunately, the tuple
assignment here doesn't quite work, since self is more like a dictionary
than a list. To set things inside self, we need to use the period scoping
operator ("."). For example, we'll want something like:
def __init__(self, name, data=None, object=None):
self.name, self.data, self.object = name, data, object
which will do the assignment.
What you had before did something different: it assigned the name "self"
to the tuple (name, data, object), which won't work. Let's take a
look again:
> def __init__(self, name, data=None, object=None):
> self = (name, data, object)
It's the situation that Shelia King ran across with references: here,
we're saying that, locally, "self" now stands for a tuple of 3 elements,
which is certainly not what we want; we want to change the object that
"self" refers to, and not redirect "self" to a new object.
In any case, with those changes in mind, the accessor functions will need
to change, since we're using "self" this way:
> def next(self):
> return self[2]
becomes:
def next(self):
return self.object
> def label(self):
> return self[0]
becomes:
def label(self):
return self.name
etc.
> However, this doesn't work:
>
> >>> from LinkedList2 import *
> >>> this = LinkedList2('thisname')
> >>> that = LinkedList2('thatname', 'somedata', this)
> >>> theother = LinkedList2('theothername', 'someotherdata', that)
> >>> print theother
>
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> File "LinkedList2.py", line 32, in __str__
> print self[0], self[1], self[2]
> AttributeError: 'LinkedList2' instance has no attribute '__getitem__'
By default, we need to change the components of self using that
period-scoping syntax. Indexing on "self" doesn't work by default; that's
where that AttributeError is coming from. However, it is possible to do
this, but it takes some extra work by using UserDict:
http://python.org/doc/current/lib/module-UserDict.html
If you use UserDict, then your code will work:
###
import UserDict
class LinkedList2(UserDict.UserDict):
def __init__(self, name, data=None, object=None):
UserDict.UserDict.__init__(self)
self[0], self[1], self[2] = name, data, object
# and everything else stays the same.
###
But you'll need to experiment with UserDict a bit, just to see how it
works. Hope this helps!