[英]How can I remove two or more objects of a list from a single input in Python?
[英]How can I remove two or more subnet from a network?
从ipaddress
class,我知道address_exclude
方法。 以下是文档中的示例:
>>> n1 = ip_network('192.0.2.0/28')
>>> n2 = ip_network('192.0.2.1/32')
>>> list(n1.address_exclude(n2))
[IPv4Network('192.0.2.8/29'), IPv4Network('192.0.2.4/30'),
IPv4Network('192.0.2.2/31'), IPv4Network('192.0.2.0/32')]
但是如果我想从网络中删除两个或更多子网怎么办? 例如,如何从 192.168.10.0/26 中删除他的子网 192.168.10.24/29 和 192.168.10.48/28? 结果应该是 192.168.10.0/28、192.168.10.16/29 和 192.168.10.32/28。
我正在尝试找到一种方法来使用address_exclude
方法编写我在脑海中使用的算法,但我做不到。 有没有一种简单的方法来实现我刚才解释的内容?
当您从另一个网络中排除一个网络时,结果可能是多个网络(原始网络被拆分) - 因此,对于要排除的网络的 rest,您需要先找到它们适合的部分,然后再排除它们。
这是一种可能的解决方案:
from ipaddress import ip_network, collapse_addresses
complete = ip_network('192.168.10.0/26')
# I chose the larger subnet for exclusion first, can be automated with network comparison
subnets = list(complete.address_exclude(ip_network('192.168.10.48/28')))
# other network to exclude
other_exclude = ip_network('192.168.10.24/29')
result = []
# Find which subnet the other exclusion will happen in
for sub in subnets:
# If found, exclude & add the result
if other_exclude.subnet_of(sub):
result.extend(list(sub.address_exclude(other_exclude)))
else:
# Other subnets can be added directly
result.append(sub)
# Collapse in case of overlaps
print(list(collapse_addresses(result)))
Output:
[IPv4Network('192.168.10.0/28'), IPv4Network('192.168.10.16/29'), IPv4Network('192.168.10.32/28')]
扩展我在@rdas 的回复上发布的脑电波,发布我的解决方案。
将初始网络拆分为您要求的最小块似乎更好,并为要删除的所有范围执行此操作。 然后将它们从列表中排除并返回结果。
from ipaddress import ip_network, collapse_addresses
def remove_ranges(mynetwork,l_of_ranges):
# find smallest chunk
l_chunk = sorted(list(set([x.split('/')[1] for x in l_of_ranges])))
l_mynetwork = list(ip_network(mynetwork).subnets(new_prefix=int(l_chunk[-1])))
l_chunked_ranges = [ ]
for nw in l_of_ranges:
l_chunked_ranges.extend(list(ip_network(nw).subnets(new_prefix=int(l_chunk[-1]))))
l_removed_networks = [ ]
for mynw in l_mynetwork:
if not mynw in l_chunked_ranges:
l_removed_networks.append(mynw)
result = list(collapse_addresses(l_removed_networks))
return [str(r) for r in result]
if __name__ == '__main__':
mynetwork = "10.110.0.0/16"
l_of_ranges = ["10.110.0.0/18","10.110.72.0/21","10.110.80.0/21","10.110.96.0/21"]
print(f"My network: {mynetwork}, Existing: {l_of_ranges} ")
a = remove_ranges(mynetwork,l_of_ranges)
print(f"Remaining: {a}")
结果:
My network: 10.110.0.0/16, Existing: ['10.110.0.0/18', '10.110.72.0/21', '10.110.80.0/21', '10.110.96.0/21']
Remaining: ['10.110.64.0/21', '10.110.88.0/21', '10.110.104.0/21', '10.110.112.0/20', '10.110.128.0/17']
这似乎是有效的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.