How to sort IP addresses stored in dictionary in Python?
Found a solution at https://www.lesinskis.com/python_sorting_IP_addresses.html All you have to do is convert the string of ip in ipaddress
import ipaddress
sortedkey = sorted(list_of_ip_instring, key = ipaddress.IPv4Address)
Use the key parameter of sorted to convert your ip to an integer, for example:
list_of_ips = ['192.168.204.111', '192.168.99.11', '192.168.102.105']
sorted(list_of_ips, key=lambda ip: long(''.join(["%02X" % long(i) for i in ip.split('.')]), 16))
EDIT:
Gryphius proposes a solution with the socket module, and so why not use it to make the conversion from ip to long as it is cleaner:
from socket import inet_aton
import struct
list_of_ips = ['192.168.204.111', '192.168.99.11', '192.168.102.105']
sorted(list_of_ips, key=lambda ip: struct.unpack("!L", inet_aton(ip))[0])
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)
You can use a custom key
function to return a sortable representation of your strings:
def split_ip(ip):
"""Split a IP address given as string into a 4-tuple of integers."""
return tuple(int(part) for part in ip.split('.'))
def my_key(item):
return split_ip(item[0])
items = sorted(ipCount.items(), key=my_key)
The split_ip()
function takes an IP address string like '192.168.102.105'
and turns it into a tuple of integers (192, 168, 102, 105)
. Python has built-in support to sort tuples lexicographically.
UPDATE: This can actually be done even easier using the inet_aton()
function in the socket
module:
import socket
items = sorted(ipCount.items(), key=lambda item: socket.inet_aton(item[0]))