sorting on IP addresses

Mark Pilgrim f8dy at my-deja.com
Tue Feb 6 11:33:18 EST 2001


In article <jacobkm-71251E.14460705022001 at news.ucsc.edu>,
  Jacob Kaplan-Moss <jacobkm at cats.ucsc.edu> wrote:
> In article <3A7F26CB.BE85C96F at esec.com.au>, Sam Wun
<swun at esec.com.au>
> wrote:
> > Does anyone know what is the quickly way to sort a list of IP
addresses?
> >
> > ie. 203.21.254.89 should be larger than 203.21.254.9

A quick-and-dirty timing test reveals that mapping the IP addresses to
packed IP addresses (via socket.inet_aton), sorting that list, and
mapping the result back to unpacked IP addresses (via socket.inet_ntoa)
is about much, much faster than defining a custom sort routine.

def packunpack(li):
    import socket
    packed = [socket.inet_aton(addr) for addr in li]
    packed.reverse()
    packed.sort()
    li = [socket.inet_ntoa(addr) for addr in packed]

def cmplambda(li):
    def cmp_ipaddress ( ip1, ip2 ):
        import string
        parts1 = map(lambda x:int(x), string.split(ip1,'.'))
        parts2 = map(lambda x:int(x), string.split(ip2,'.'))
        comparisons = map ( lambda x,y: cmp(x,y), parts1, parts2 )
        return reduce ( lambda x,y: x or y, comparisons )
    li.sort(cmp_ipaddress)

def cmpfor(li):
    def ip_compare( a, b ):
      """a and b are valid IP addresses of the form w.x.y.z."""
      la = [int(n) for n in a.split(".")]
      lb = [int(n) for n in b.split(".")]
      for pair in zip(la, lb):
          if pair[0] > pair[1]:
            return -1
          elif pair[0] < pair[1]:
            return 1
      return 0
    li.sort(ip_compare)

def makelist():
    import random
    li = []
    for i in range(10000):
        li.append("%s.%s.%s.%s" % (random.randint(0, 255),
random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
    return li

def timedsort(li, funcname):
    import time
    func = eval(funcname)
    startTime = time.time()
    func(li)
    endTime = time.time()
    print funcname.ljust(20), str(endTime - startTime)

if __name__ == "__main__":
    li = makelist()
    timedsort(li[:], "packunpack")
    timedsort(li[:], "cmplambda")
    timedsort(li[:], "cmpfor")

##Output (smaller numbers are better):
packunpack           0.230000019073
cmplambda            15.3830000162
cmpfor               9.73399996758

-M
--
You're smart; why haven't you learned Python yet?
http://diveintopython.org/


Sent via Deja.com
http://www.deja.com/



More information about the Python-list mailing list