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

新手上路,请多包涵

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

 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)

它对 IP 进行排序,但像这样:

 192.168.102.105
192.168.204.111
192.168.99.11

这还不够好,因为它无法识别 99 是小于 102 或 204 的数字。我希望输出如下所示:

 192.168.99.11
192.168.102.105
192.168.204.111

我找到 了这个,但我不确定如何在我的代码中实现它,或者因为我使用字典,它是否有可能实现。我在这里有什么选择?

原文由 tkit 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 541
2 个回答

您可以使用自定义 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)

split_ip() 函数采用 IP 地址字符串,如 '192.168.102.105' 并将其转换为整数元组 (192, 168, 102, 105) 。 Python 内置支持按字典顺序对元组进行排序。

更新:实际上,使用 socket 模块中的 inet_aton() 函数可以更轻松地完成此操作:

 import socket
items = sorted(ipCount.items(), key=lambda item: socket.inet_aton(item[0]))

原文由 Ferdinand Beyer 发布,翻译遵循 CC BY-SA 3.0 许可协议

使用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))

编辑:

Gryphius 提出了一个带有 socket 模块的解决方案,所以为什么不使用它来进行从 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])

原文由 user610650 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题