因此,对于单数搜索:
from netaddr import IPAddress, IPNetwork
if IPAddress( address ) in IPNetwork( network ):
print( 'in' )
但是,如果您获得了网络列表怎么办?可以在不使用for循环的情况下这样做吗?做这项任务的Pythonic方法是什么?...最好可读,然后更快。
from netaddr import IPAddress, IPNetwork
networks = [
'1.0.0.08',
'2.0.0.08',
# ...
'21.22.14.024' # something random
]
for network in networks:
if IPAddress( address ) in IPNetwork( network ):
print( 'in' )
break
编辑:对于任何有兴趣的人,我获取了给定的网络列表,并将每个网络扩展到其地址列表。然后我列出了地址列表,并从中列出了一套。鉴于集合具有O(1)查找,我认为这会有所帮助。
使用for循环(无设置)所需的时间为24分钟。
使用的时间:
address_set = set()
for network in networks:
for address in IPNetwork( network ).subnet( 32 ):
non_CIDR_address = str( address ).split( '/' )[ 0 ]
address_set.add( non_CIDR_address )
if query_address in address_set:
print( 'in' )
if address in address_set:
print( 'in' )
...是2分37秒。
Go Sets!
谨慎:扩展网络可能很昂贵。
if any(IPAddress(address) in IPNetwork(network) for network in networks):
...
优化只能通过一次实例化IPAddress
,然后在列表中存储IPNetwork
s。
(这些都不是python的,因此,如果这个问题确实是关于语法和编码样式,则此答案对此无能贡献。基本上,它在我的想法上有所扩展Abarnert在评论中提出建议。)
这是不需要以做出基本假设和构建搜索树的代价在所有范围上循环的东西:假设您要检查的范围是不重叠的(即没有两个范围包含一些共享的IP),您,您可以为您的范围构造一个搜索树,然后在适当地调整树的搜索功能后,在您有序的范围中搜索O(log n)
中的IP(甚至范围),这非常简单。
如果您的范围重叠,则可能需要查看间隔树,您应该可以轻松地应用于该情况。
只有在要多次以非平凡的网络进行维护的情况下查询很多次时,两者都将很有用。如果您实际上只需要随时处理50个网络,那应该是微不足道的,并在列表中立即工作。