如何在Python中对存储在字典中的IP地址进行排序?

poo*_*zko 15 python sorting ip dictionary

我有一段看起来像这样的代码:

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)
Run Code Online (Sandbox Code Playgroud)

它有点排序IP,但是像这样:

192.168.102.105
192.168.204.111
192.168.99.11
Run Code Online (Sandbox Code Playgroud)

这是不够好,因为它不能识别99是一个小于102或204的数字.我希望输出是这样的:

192.168.99.11
192.168.102.105
192.168.204.111
Run Code Online (Sandbox Code Playgroud)

我找到了这个,但我不知道如何在我的代码中实现它,或者甚至可能因为我使用字典.我有什么选择?谢谢..

Fer*_*yer 35

您可以使用自定义key函数返回字符串的可排序表示:

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)
Run Code Online (Sandbox Code Playgroud)

split_ip()函数接受一个I​​P地址字符串'192.168.102.105',并将其转换为整数元组(192, 168, 102, 105).Python内置支持按字典顺序对元组进行排序.

更新:使用模块中的inet_aton()函数实际上可以更容易地完成socket:

import socket
items = sorted(ipCount.items(), key=lambda item: socket.inet_aton(item[0]))
Run Code Online (Sandbox Code Playgroud)

  • 您也可以使用`map`函数执行此操作:`sorted(ipCount.items(),key = lambda x:tuple(map(int,x.split('.')))))` (2认同)

小智 12

使用sorted的key参数将ip转换为整数,例如:

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))
Run Code Online (Sandbox Code Playgroud)

编辑:

Gryphius提出了一个带有套接字模块的解决方案,所以为什么不使用它来进行从ip到long的转换,因为它更干净:

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])
Run Code Online (Sandbox Code Playgroud)


Pan*_*aha 7

在https://www.lesinskis.com/python_sorting_IP_addresses.html找到了解决方案 您所要做的就是转换 ipaddress 中的 ip 字符串

import ipaddress
sortedkey = sorted(list_of_ip_instring, key = ipaddress.IPv4Address)
Run Code Online (Sandbox Code Playgroud)


Jax*_*t0r 6

处理正确顺序的一种干净方法是使用 Python 的ipaddress模块。您可以将字符串转换为IPv4Address表示形式,然后对它们进行排序。这是一个带有列表对象的工作示例(用 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)
Run Code Online (Sandbox Code Playgroud)