繁体   English   中英

在Python列表中的IP地址的最后一个八位位组上排序

[英]Sort on the last octet of an IP address in a Python list

这有点令人困惑(至少对我而言)。 我正在使用一个简单的Python脚本使用fping返回“启动”主机的列表。 我将每个“ up”主机存储在Python列表中,但是list.sort()显然不会基于存储为字符串的IP地址的最后一个八位位组进行排序。 我想对降序的.1,.2,.3等进行排序。

这是代码的一部分:

for addr in os.popen("fping -a -q -g " + subnet):
    addr = addr.rstrip('\n')
    addr_list.append(addr)

addr_list.sort()
for ip in addr_list:
    print ip

对于最后一个八位位组,您可以在密钥中使用rsplit()

addr_list = [  # Thanks @aneroid
    '10.11.12.13',
    '1.2.3.4',
    '127.0.0.1',
    '192.168.0.1',
]

>>> sorted(addr_list, key=lambda x: int(x.rsplit('.', 1)[1]), reverse=True)
['10.11.12.13', '1.2.3.4', '127.0.0.1', '192.168.0.1']

哪个在下降-但您的示例似乎在上升:

>>> sorted(addr_list, key=lambda x: int(x.rsplit('.', 1)[1]))
['127.0.0.1', '192.168.0.1', '1.2.3.4', '10.11.12.13']

但是我想我更喜欢按照@aneroid进行元组排序:

>>> sorted(addr_list, key=lambda x: tuple(map(int, reversed(x.split('.')))))
['127.0.0.1', '192.168.0.1', '1.2.3.4', '10.11.12.13']

假设您的addr_list列表如下所示(您尚未在问题中指定它):

addr_list = [
    '10.11.12.13',
    '1.2.3.4',
    '127.0.0.1',
    '192.168.0.1',
]

在上分裂. ,并使用最后一项(最后一个八位位组)作为排序的键。 当然,对于“ 127.0.0.1”和“ 192.168.0.1”,您可能想要然后对倒数第二个字节进行排序,然后对倒数第三个字节进行排序,然后对第一个字节进行排序。

因此,使用此行为作为key

>>> list(reversed('10.11.12.13'.split('.')))
['13', '12', '11', '10']
>>> sorted(addr_list, key=lambda ip: list(reversed(ip.split('.'))))
['127.0.0.1', '192.168.0.1', '10.11.12.13', '1.2.3.4']

注意134之前被列出。 因此,还要确保将每个项目都比较为数字而不是字符串:

>>> sorted(addr_list, key=lambda ip: map(int, reversed(ip.split('.'))))
['127.0.0.1', '192.168.0.1', '1.2.3.4', '10.11.12.13']

将其分配给另一个列表或进行就地排序:

>>> addr_list.sort(key=lambda ip: map(int, reversed(ip.split('.'))))
>>> addr_list
['127.0.0.1', '192.168.0.1', '1.2.3.4', '10.11.12.13']

sort可以将函数用于执行比较作为参数。 该函数接受两个输入,如果第一个参数较大,则返回1如果第二个参数较大,则返回-1 0如果它们相等,则返回0 ,以进行排序。 这是适合您的情况的功能:

def compare_ips(ip1, ip2):
    last_octet1 = int(ip1.split('.')[-1]) # splits the ip and grabs the last octet
    last_octet2 = int(ip2.split('.')[-1]) # splits the ip and grabs the last octet
    if last_octet1 > last_octet2:
        return 1
    if last_octet1 < last_octet2:
        return -1
    return 0

然后,您只需将其作为关键字参数进行排序即可:

>>> ips = ['192.168.1.101', '251.39.0.103', '127.0.0.1']
>>> ips.sort(cmp = compare_ips)
>>> ips
['127.0.0.1', '192.168.1.101', '251.39.0.103']

鉴于最后一个八位位组通常会告诉您有关地址的更多信息(例如,可公开路由的地址的国家/地区,较小网络的子网),仅按最后一个八位位组进行排序是一个非常奇怪的要求。

更笼统地说,这将按IP地址的数字表示形式对列表进行排序:

import socket
ip_list = ['192.168.1.120', '192.168.1.30',  '127.0.0.1']

# numeric sort, leveraging inet_pton to convert valid IPv4 address
# notation to a 'packed' string of 4 bytes, which will then sort correctly.
print sorted(ip_list, key=lambda (x): socket.inet_pton(socket.AF_INET, x))

# strict string-based sort for comparison
print sorted(ip_list)

或者,如果您不想为inet_pton使用套接字模块:

def ip2int(ipstr):
    octets = [int(x) for x in ipstr.split('.')]
    return sum( (o << (8 * 3-i) for i,o in enumerate(octets)) )
sorted(ip_list, key=ip2int)
addr_list = [
    '10.11.12.3',
    '1.2.3.4',
    '127.0.0.1',
    '192.168.0.2',
]

# lambda x=192.168.0.2 , ip.split= ['192','168','0','2'][-1] = 2
sorted_ips = sorted(addr_list , key=lambda ip: ip.split('.')[-1])
for ip in sorted_ips:
  print(ip)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM