Best way to make a list unique?

Marc Christiansen tolot at jupiter.solar-empire.de
Wed Mar 9 08:35:11 EST 2005


Michael Spencer <mahs at telcopartners.com> wrote:

Nice. When you replace None by an object(), you have no restriction on
the elements any more:

> Here's something to work with:
> 
> class OrdSet(object):
>     def __init__(self, iterable):
>         """Build an ordered, unique collection of hashable items"""
>         #self._data = {None:[None, None]} # None is the pointer to the first
>         #                                 # element.  This is unsatisfactory
>         #                                 # because it cannot then be a
>         #                                 # member of the collection
>         #self._last = None
          self._last = self._root = root = object()
          self._data = {root:[root, root]}
>         self.update(iterable)
> 
>     def add(self, obj):
>         """Add an element to the collection"""
>         data = self._data
>         if not obj in data:
>             last = self._last
>             data[last][1] = obj
>             #data[obj] = [last, None]
              data[obj] = [last, self._root]
>             self._last = obj
> 
>     def update(self, iterable):
>         """Update the collection with the union of itself and another"""
>         obj = self._last
>         data = self._data
>         last = data[obj][0]
>         for item in iterable:
>             if item not in data:
>                 data[obj] = [last, item]
>                 last, obj = obj, item
>         #data[obj] = [last, None]
          data[obj] = [last, self._root]
>         self._last = obj
> 
>     def remove(self, item):
>         """Remove an element from a set; it must be a member.
> 
>             If the element is not a member, raise a KeyError."""
>         data = self._data
>         prev, next = data[item]
>         data[prev][1] = next
>         data[next][0] = prev
> 
>     def discard(self, item):
>         """Remove an element from a set if it is a member.
>             If the element is not a member, do nothing."""
>         try:
>             self.remove(item)
>         except KeyError:
>             pass
> 
>     def __contains__(self, item):
>         return item in self._data
> 
>     def pop(self):
>         """Remove and the return the oldest element"""
>         data = self._data
>         #prev, first =  data[None]
>         #data[None] = [None,data[first][1]]
          root = self._root
          prev, first =  data[root]
          data[root] = [root,data[first][1]]
>         return first
> 
>     def clear(self):
>         self.__init__([])
> 
>     def __iter__(self):
>         """Iterate over the collection in order"""
>         data = self._data
>         #prev, next = data[None]
>         #while next is not None:
          root = self._root
          prev, next = data[root]
          while next is not root:
>             yield next
>             prev, next = data[next]
> 
>     def __len__(self):
>         return len(self._data)-1
> 
>     def __repr__(self):
>         return "%s(%s)" % (self.__class__.__name__,list(self))

>>> a=OrdSet([None,1,None,3])
>>> a
OrdSet([None, 1, 3])

Marc



More information about the Python-list mailing list