python ipaddress,仅获取第一个可用的主机?
python ipaddress, get first usable host only?
我正在使用 pythons ipaddress 模块,我试图只获取第一个可用主机,而不是所有可用主机
下面为我提供了所有主机,当我尝试对其编制索引时,出现以下错误。
是否可以通过任何其他方式获得第一个可用主机?
谢谢
n = ipaddress.ip_network(u'10.10.20.0/24')
for ip in n.hosts():
... print ip
10.10.20.1
10.10.20.2
10.10.20.3
10.10.20.4
...
>>> for ip in n.hosts():
... print ip[1]
...
Traceback (most recent call last):
File "<console>", line 2, in <module>
TypeError: 'IPv4Address' object does not support indexing
>>>
下面的也失败了
>>> print n.hosts()[0]
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: 'generator' object has no attribute '__getitem__'
hosts()
returns 生成器对象,不支持索引。您必须遍历它。
如果你只想要第一个元素,只需使用next()
:
n = ipaddress.ip_network(u'10.10.20.0/24')
first_host = next(n.hosts())
如果要将生成器对象转换为支持索引的列表,必须调用list()
函数:
all_hosts = list(n.hosts())
first_host = all_hosts[0]
您还可以像在列表中一样循环遍历生成器对象,就像您在第一个代码片段中所做的那样:
for ip in n.hosts():
# do something with ip: this is the IP address, so don't try to index into it!
pass
获取第一个主机地址特别是"big networks"/小前缀值的替代方法是:
In [2]: ip_network("10.10.20.0/24")[1]
Out[2]: IPv4Address('10.10.20.1')
根本不需要使用 hosts() 生成器。参见例如https://docs.python.org/3/library/ipaddress.html#networks-as-containers-of-addresses 关于 ipaddress 网络对象 "containers of addresses"。此地址 space / "container of addresses" 中的第一个地址是网络地址(索引 [0])。最后地址是广播地址(索引[-1])。
或者您可以使用网络地址并通过添加 1 获得第一个主机地址:
In [4]: ip_network("10.10.20.0/24").network_address + 1
Out[4]: IPv4Address('10.10.20.1')
根据您使用的前缀/网络掩码,hosts() 生成器可能很慢。如果你使用
list(ip_network("10.0.0.0/8").hosts())
该语句创建了一个包含 2**(32-8) - 2 = 16777214 个条目的列表
如果我对这个语句计时,创建这个主机列表需要 > 10 秒:
In [11]: %time len(list(ip_network("10.0.0.0/8").hosts()))
Wall time: 13.6 s
Out[11]: 16777214
如果我比较获取第一个地址所需的时间:
In [15]: %time list(ip_network("10.0.0.0/8").hosts())[0]
Wall time: 13.6 s
Out[15]: IPv4Address('10.0.0.1')
In [13]: %timeit -n10 -r5 ip_network("10.0.0.0/8")[1]
10 loops, best of 5: 11.8 µs per loop
In [17]: %timeit -n10 -r5 ip_network("10.0.0.0/8").network_address + 1
10 loops, best of 5: 9.16 µs per loop
结果:hosts() 需要大约 14 秒才能完成。备选方案是 +/- 10 µs
/24 网络的时间:
In [19]: %timeit -n10 -r5 list(ip_network("10.0.0.0/24").hosts())[0]
10 loops, best of 5: 135 µs per loop
In [20]: %timeit -n10 -r5 ip_network("10.0.0.0/24").network_address + 1
10 loops, best of 5: 9.32 µs per loop
简短版本:
import ipaddress
net=ipaddress.ip_network(u'1.0.0.0/8')
first=str(net[1])
last=str(net[-2])
长版:
这显示了计算第一个和最后一个可用 IP 地址的 3 种方法
在使用 ipaddress 的 CIDR 块中。
它显示了 "right"(快速、space 有效的方法)
和另外两个使用 hosts 迭代器的结果是
举例说明经典的 space 时间权衡。
import ipaddress
import time
import sys
#
# The fast, memory efficient way
#
start = time.time()
net=ipaddress.ip_network(u'1.0.0.0/8')
first=str(net[1])
last=str(net[-2])
stop = time.time()
seconds=stop-start
size=sys.getsizeof(net)
print("First Host: %s, Last Host: %s, Seconds: %.4f, Size (Mb): %d" % (first,last, seconds, size/(1024**2)))
#
# Space efficient, but slow
#
start = time.time()
net=ipaddress.ip_network(u'1.0.0.0/8')
iterator=ipaddress.ip_network(u'1.0.0.0/8').hosts()
first = last = next(iterator, None)
for last in iterator:
pass
first=str(first)
last=str(last)
stop = time.time()
seconds=stop-start
size=sys.getsizeof(net)
print("First Host: %s, Last Host: %s, Seconds: %.4f, Size (Mb): %d" % (first,last, seconds, size/(1024**2)))
#
# Memory hog and slow, the worst of both worlds.
#
start = time.time()
hosts=list(ipaddress.ip_network(u'1.0.0.0/8').hosts())
first_host=str(hosts[0])
last_host=str(hosts[-1])
size=sys.getsizeof(hosts)
stop = time.time()
seconds=stop-start
print("First Host: %s, Last Host: %s, Seconds: %.4f, Size (Mb): %d" % (first,last, seconds, size/(1024**2)))
First Host: 1.0.0.1, Last Host: 1.255.255.254, Seconds: 0.0000, Size (Mb): 0
First Host: 1.0.0.1, Last Host: 1.255.255.254, Seconds: 8.0086, Size (Mb): 0
First Host: 1.0.0.1, Last Host: 1.255.255.254, Seconds: 11.8096, Size (Mb): 132
我正在使用 pythons ipaddress 模块,我试图只获取第一个可用主机,而不是所有可用主机
下面为我提供了所有主机,当我尝试对其编制索引时,出现以下错误。
是否可以通过任何其他方式获得第一个可用主机?
谢谢
n = ipaddress.ip_network(u'10.10.20.0/24')
for ip in n.hosts():
... print ip
10.10.20.1
10.10.20.2
10.10.20.3
10.10.20.4
...
>>> for ip in n.hosts():
... print ip[1]
...
Traceback (most recent call last):
File "<console>", line 2, in <module>
TypeError: 'IPv4Address' object does not support indexing
>>>
下面的也失败了
>>> print n.hosts()[0]
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: 'generator' object has no attribute '__getitem__'
hosts()
returns 生成器对象,不支持索引。您必须遍历它。
如果你只想要第一个元素,只需使用next()
:
n = ipaddress.ip_network(u'10.10.20.0/24')
first_host = next(n.hosts())
如果要将生成器对象转换为支持索引的列表,必须调用list()
函数:
all_hosts = list(n.hosts())
first_host = all_hosts[0]
您还可以像在列表中一样循环遍历生成器对象,就像您在第一个代码片段中所做的那样:
for ip in n.hosts():
# do something with ip: this is the IP address, so don't try to index into it!
pass
获取第一个主机地址特别是"big networks"/小前缀值的替代方法是:
In [2]: ip_network("10.10.20.0/24")[1]
Out[2]: IPv4Address('10.10.20.1')
根本不需要使用 hosts() 生成器。参见例如https://docs.python.org/3/library/ipaddress.html#networks-as-containers-of-addresses 关于 ipaddress 网络对象 "containers of addresses"。此地址 space / "container of addresses" 中的第一个地址是网络地址(索引 [0])。最后地址是广播地址(索引[-1])。
或者您可以使用网络地址并通过添加 1 获得第一个主机地址:
In [4]: ip_network("10.10.20.0/24").network_address + 1
Out[4]: IPv4Address('10.10.20.1')
根据您使用的前缀/网络掩码,hosts() 生成器可能很慢。如果你使用
list(ip_network("10.0.0.0/8").hosts())
该语句创建了一个包含 2**(32-8) - 2 = 16777214 个条目的列表
如果我对这个语句计时,创建这个主机列表需要 > 10 秒:
In [11]: %time len(list(ip_network("10.0.0.0/8").hosts()))
Wall time: 13.6 s
Out[11]: 16777214
如果我比较获取第一个地址所需的时间:
In [15]: %time list(ip_network("10.0.0.0/8").hosts())[0]
Wall time: 13.6 s
Out[15]: IPv4Address('10.0.0.1')
In [13]: %timeit -n10 -r5 ip_network("10.0.0.0/8")[1]
10 loops, best of 5: 11.8 µs per loop
In [17]: %timeit -n10 -r5 ip_network("10.0.0.0/8").network_address + 1
10 loops, best of 5: 9.16 µs per loop
结果:hosts() 需要大约 14 秒才能完成。备选方案是 +/- 10 µs
/24 网络的时间:
In [19]: %timeit -n10 -r5 list(ip_network("10.0.0.0/24").hosts())[0]
10 loops, best of 5: 135 µs per loop
In [20]: %timeit -n10 -r5 ip_network("10.0.0.0/24").network_address + 1
10 loops, best of 5: 9.32 µs per loop
简短版本:
import ipaddress
net=ipaddress.ip_network(u'1.0.0.0/8')
first=str(net[1])
last=str(net[-2])
长版:
这显示了计算第一个和最后一个可用 IP 地址的 3 种方法 在使用 ipaddress 的 CIDR 块中。
它显示了 "right"(快速、space 有效的方法) 和另外两个使用 hosts 迭代器的结果是 举例说明经典的 space 时间权衡。
import ipaddress
import time
import sys
#
# The fast, memory efficient way
#
start = time.time()
net=ipaddress.ip_network(u'1.0.0.0/8')
first=str(net[1])
last=str(net[-2])
stop = time.time()
seconds=stop-start
size=sys.getsizeof(net)
print("First Host: %s, Last Host: %s, Seconds: %.4f, Size (Mb): %d" % (first,last, seconds, size/(1024**2)))
#
# Space efficient, but slow
#
start = time.time()
net=ipaddress.ip_network(u'1.0.0.0/8')
iterator=ipaddress.ip_network(u'1.0.0.0/8').hosts()
first = last = next(iterator, None)
for last in iterator:
pass
first=str(first)
last=str(last)
stop = time.time()
seconds=stop-start
size=sys.getsizeof(net)
print("First Host: %s, Last Host: %s, Seconds: %.4f, Size (Mb): %d" % (first,last, seconds, size/(1024**2)))
#
# Memory hog and slow, the worst of both worlds.
#
start = time.time()
hosts=list(ipaddress.ip_network(u'1.0.0.0/8').hosts())
first_host=str(hosts[0])
last_host=str(hosts[-1])
size=sys.getsizeof(hosts)
stop = time.time()
seconds=stop-start
print("First Host: %s, Last Host: %s, Seconds: %.4f, Size (Mb): %d" % (first,last, seconds, size/(1024**2)))
First Host: 1.0.0.1, Last Host: 1.255.255.254, Seconds: 0.0000, Size (Mb): 0
First Host: 1.0.0.1, Last Host: 1.255.255.254, Seconds: 8.0086, Size (Mb): 0
First Host: 1.0.0.1, Last Host: 1.255.255.254, Seconds: 11.8096, Size (Mb): 132