[Tutor] Uniques values in a list

Alexandre Ratti alex@gabuzomeu.net
Sun, 17 Mar 2002 17:56:21 +0100


Hello,


At 08:28 17/03/2002 -0500, you wrote:
>From: "Raymond Hettinger" <python@rcn.com>
>Subject: Re: [Tutor] Uniques values in a list
>Date: Sun, 17 Mar 2002 08:28:10 -0500

[Filtering out unique values from a list.]

> > => Do you know any other solution (eg. using functional programming or
> > similar woodoo)?
>
>Here are the winning functions from a speed test of various implementations:

>def uniq4(alist):                       # Fastest non-order preserving
>     set = {}
>     map(set.__setitem__, alist, [])     # memory: [None]*n + {key:None}*u
>     return set.keys()

I modified this solution to run under Python 2.x:

def filterListWithMap21(aList):
     "Returns a list of unique list items."
     set = {}
     map(set.setdefault, aList, [])
     return set.keys()

I'm not sure what is the correct way to test these functions; I get 
inconsistent results.

- Here is my timer function:

import time

def actionTimer(action, *param):
     "Times an action."
     startTime = time.clock()
     action(*param)
     endTime = time.clock()
     return endTime - startTime

- Here is the function I use to create a list of values with duplicated 
entries:

import random

def createList(itemCount):
     "Returns a list filled with itemCount items."
     theList = []
     random.seed()
     for n in range(itemCount):
         theList.append(random.choice(range(50)))
     print "Item count: %i" % len(theList)
     return theList

- And here is the test function:

import sys

def runTest(itemCount = 50000):

     startList = createList(itemCount)

     sourceList = startList[:]
     assert sourceList == startList
     assert sourceList is not startList

     print "Using a second list..."
     print actionTimer(filterListWithList, sourceList)

     sourceList = startList[:]
     print "Using a dictionary..."
     print actionTimer(filterListWithDict, sourceList)

     sourceList = startList[:]
     print "Using in place filtering..."
     print actionTimer(filterListInPlace, sourceList)

     sourceList = startList[:]
     print "Using list comprehension (Python 2.1)..."
     print actionTimer(filterListWithComprehension21, sourceList)

     sourceList = startList[:]
     print "Using map (Python 2.1)..."
     print actionTimer(filterListWithMap21, sourceList)

     sourceList = startList[:]
     print "Using map and operator.setitem..."
     print actionTimer(filterListWithMapAndOperator, sourceList)

     # If version >= 2.2
     if eval(sys.version[:3]) >= 2.2:

         sourceList = startList[:]
         print "Using list comprehension (Python 2.2)..."
         print actionTimer(filterListWithComprehension22, sourceList)

         sourceList = startList[:]
         print "Using map (Python 2.2)..."
         print actionTimer(filterListWithMap22, sourceList)


Do they look reasonable?


Cheers.

Alexandre