[Tutor] hash()ing a list

Orri Ganel singingxduck at gmail.com
Mon Mar 28 23:06:37 CEST 2005


Well, what I ended up doing is making it so that Nodes are equal if
they have the same 'cargo', but hash based on memory address.  If this
wasn't the case, I either wouldn't be able to have multiple Nodes with
the same 'cargo' in a LinkedList, or I wouldn't be able to sort them
properly, among other things.  Even as is, however, its not a big
deal, because in order to access a value with a Node whose 'cargo' is
the same as the key, I only have to do a bit of maneuvering, while if
I want to make sure I have the right Node in self.__get__(self,
index=0), it takes no manuevering at all:

Python 2.4.1c2 (#64, Mar 17 2005, 11:11:23) [MSC v.1310 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.

    ****************************************************************
    Personal firewall software may warn about the connection IDLE
    makes to its subprocess using this computer's internal loopback
    interface.  This connection is not visible on any external
    interface and no data is sent to or received from the Internet.
    ****************************************************************
    
IDLE 1.1      
>>> a = LinkedList(range(10))
>>> a.appendlist(range(9,-1,-1))
True
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> a[-2]
<__main__.Node instance at 0x00C5E580>
>>> print _
1
>>> a.lltopl[_]
1
>>> [a.lltopl.keys()[i] for i in range(len(a.lltopl)) if
a.lltopl.keys()[i] == Node(1)]
[<__main__.Node instance at 0x00C5E580>, <__main__.Node instance at 0x00C5A558>]
>>> for i in _:
	print i

	
1
1

The reason this makes a difference is because, if Nodes are hashed
based on memory location and are *not* equal based on cargo, it
becomes impossible to sort with a cmp parameter because I'd already be
sorting based on cargo:

def sort(self, key=None, reverse=False):
               """LL.sort() -- stable sort *IN PLACE*"""
               unsort = self.lltopl.keys()[:]
               unsort.sort(lambda x, y: cmp(x.cargo, y.cargo), key, reverse)
               self.head = unsort[0]
               self.head.prev = None
               self.tail = unsort[-1]
               self.tail.next = None
               nod = self.head
               i = 1
               while i < len(unsort):
                   nod.next = unsort[i]
                   nod = nod.next
                   i += 1
               nod = self.tail
               i = len(unsort)-2
               while i >= 0:
                   nod.prev = unsort[i]
                   nod = nod.prev
                   i -= 1
               self.pylist.sort(key=key, reverse=reverse)
               return self.pylist

Otherwise, the *sorting* becomes memory address-based.  I guess what
it comes down to is that for me, it's more intuitive to sort based on
cargo and still allow multiple "equal" Nodes in a dictionary than to
sort based on cargo and disallow multiple "equal" Nodes, and more so
than to sort based on memory address and allow multiple "equal" Nodes
in a dictionary.  This method gives me the most intuitivity with no
loss, from what I can see.  In any case, I will soon be posting the
entire code (via rafb.net/paste) for suggestions/comments.

Thanks,
Orri

-- 
Email: singingxduck AT gmail DOT com
AIM: singingxduck
Programming Python for the fun of it.


More information about the Tutor mailing list