Python递归地在列表中查找列表(n deep)

2024-04-30 04:52:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用ipaddress(https://docs.python.org/3/library/ipaddress.html)解决以下问题:

我的BGP聚合地址是10.76.32.0/20

我想从中减去同一路由器上的所有网络命令,以确定聚合地址是否大于定义的网络,以及是否有剩余的可用网络空间。你知道吗

这种情况下的网络是:

10.76.32.0/24条 10.76.33.0/24 10.76.34.0/24 10.76.35.0/24 10.76.36.0/24 10.76.37.0/24 10.76.38.0/24 10.76.39.0/24 10.76.40.0/24 10.76.41.0/24 10.76.42.0/24 10.76.43.0/24 10.76.44.0/25 10.76.44.128/25 10.76.45.0/24 10.76.46.0/24 10.76.47.240/30 10.96.208.219/32段

使用ipaddress.address\u排除(网络)我可以从聚合地址中减去一个网络,操作返回一个iterable对象。你知道吗

然后我可以在这个iterable对象上做一个for循环,看看它是否包含任何其他网络,但如果它包含了,我将得到另一个iterable对象作为结果。这个过程可以假设将列表中的列表返回到未指定的深度。你知道吗

我的问题是,是否有人知道如何在任意深度的列表中找到这样一个列表结构中的所有元素。你知道吗

饥饿

编辑:谢谢你的回答。我还没来得及检查它,但我确实找到了一种方法,不必使用netaddr中的.issubset方法进行递归:

def undeclared_in_aggregate(aggregate, network):
    remaining = []
    composite = []
    for a_cidr in aggregate:
        a_cidr = IPSet([a_cidr])
        for n_cidr in network:
            n_cidr = IPSet([n_cidr])
            if n_cidr.issubset(a_cidr):
                a_cidr.remove(n_cidr.iprange())
                remaining = re.sub(r'IPSet\(\[|\]\)|\'', '', str(a_cidr))
                remaining = remaining.split(',')
                if remaining == ['']:
                    remaining = []
        composite += remaining
    return composite

这将以列表格式获取聚合地址和网络,并将差异作为新列表返回(每个聚合地址)。你知道吗

对于上述示例: ['10.76.47.0/25'、'10.76.47.128/26'、'10.76.47.192/27'、'10.76.47.224/28'、'10.76.47.244/30'、'10.76.47.248/29']


Tags: 对象方法in网络列表for地址ipset
1条回答
网友
1楼 · 发布于 2024-04-30 04:52:35

你没有指明你正在使用的python(2或3)的版本,所以我假设它是python3,因为你发布的链接指向python3文档。您没有发布任何代码,但根据您对问题的描述,我假设您需要以下内容:

from ipaddress import ip_network, summarize_address_range
from itertools import chain

def exclude_multiple(super_network, networks):
    networks = sorted(networks, key=lambda n:n.network_address)
    starts = (n.broadcast_address + 1 for n in networks)
    starts = chain([super_network.network_address], starts)
    ends = (n.network_address - 1 for n in networks)
    ends = chain(ends, [super_network.broadcast_address])
    return ((s, e) for s, e in zip(starts, ends) if s != e + 1)  # s-1 != (e+1) - 1

networks = [
 '10.76.32.0/24',
 '10.76.33.0/24',
 # more here
]
networks = map(ip_network, networks)
super_network = ip_network('10.76.32.0/20')
free_ranges = exclude_multiple(super_network, networks)
free_networks = (summarize_address_range(f, l) for f, l in free_ranges)
free_networks = list(chain.from_iterable(free_networks))

此代码不包含范围检查,因此如果networks重叠或超出super_network范围,您将从summarize_address_range得到一个非常有用的错误,但是范围检查可以通过一些调整来添加。你知道吗

相关问题 更多 >