How to sort IP addresses stored in dictionary in Python?

Viewed 35146

I have a piece of code that looks like this:

ipCount = defaultdict(int)

for logLine in logLines:
    date, serverIp, clientIp = logLine.split(" ")
    ipCount[clientIp] += 1

for clientIp, hitCount in sorted(ipCount.items(), key=operator.itemgetter(0)):
    print(clientIp)

and it kind of sorts IP's, but like this:

192.168.102.105
192.168.204.111
192.168.99.11

which is not good enough since it does not recognize that 99 is a smaller number than 102 or 204. I would like the output to be like this:

192.168.99.11
192.168.102.105
192.168.204.111

I found this, but I am not sure how to implement it in my code, or if it is even possible since I use dictionary. What are my options here?

9 Answers

A clean way of handling the right order is using Pythons ipaddress module. You can transform the Strings into IPv4Address representations and sort them afterwards. Here's a working example with list objects (Tested with Python3):

import ipaddress

unsorted_list = [
  '192.168.102.105',
  '192.168.204.111',
  '192.168.99.11'
]

new_list = []

for element in unsorted_list:
  new_list.append(ipaddress.ip_address(element))

new_list.sort()

# [IPv4Address('192.168.99.11'), IPv4Address('192.168.102.105'), IPv4Address('192.168.204.111')]
print(new_list)

in python 3

use like this:

import ipaddress

clientIp = sorted(clientIp, key=ipaddress.IPv4Address)

for ip in clientIp:
    print(ip)

and when IP addresses are Classless Inter-Domain Routing (CIDR) use:

import ipaddress

clientIp = sorted(clientIp, key=ipaddress.IPv4Network)

for ip in clientIp:
    print(ip)

how about not working with strings at all and instead convert each octet into integer, then passing it into 4 dimensional dictionary?

ClientIps[192][168][102][105]=1
ClientIps[192][168][99][11]=1

then it is easy to just sort an array by key, isnt it?

for key1, value in sorted(ClientIps.items()): 
  for key2, value in sorted(ClientIps[key1].items()): 
    for key3, value in sorted(ClientIps[key1][key2].items()): 
      for key4, value in sorted(ClientIps[key][key2][key3].items()): 
        print(key1, key2, key3, key4)

for speed reasons it may be beneficial to also compare simple python dictionary against OrderedDict .

Related