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()函数接受一个IP地址字符串'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)
小智 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)
在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)
处理正确顺序的一种干净方法是使用 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)