3
\$\begingroup\$

The below algorithm is supposed to take a list of input IPs/networks and a list of IPs/networks to exclude, and return a list of networks that don't include any of the IPs/networks to exclude...

Please review it and provide me with some feedback!

import ipaddress
from ipaddress import IPv4Network

def recurse_exclude(supernet_list, exclude_list):
    # For some reason, this only works if we force the generators into lists
    for supernet in list(supernet_list):
        for exclude in exclude_list:
            try:
                excluded_list = recurse_exclude(list(supernet.address_exclude(exclude)), exclude_list)
            except ValueError:
                # Ignore when the IP/net to exclude was not in the supernet
                continue
            else:
                return list(excluded_list)
    return supernet_list

supernet_list = [IPv4Network('1.1.0.0/24')]
output = recurse_exclude(supernet_list, exclude_list=[IPv4Network('1.1.0.0/25'),IPv4Network('1.1.0.128/26')])
\$\endgroup\$
2
  • \$\begingroup\$ Please clarify your intentions. If you're looking for an explanation of the code provided, we don't do that. Does the code work to your satisfaction? \$\endgroup\$
    – Mast
    Jul 23, 2020 at 16:27
  • \$\begingroup\$ I wrote this code, I was hoping for some feedback on my logic. I shall change the title \$\endgroup\$
    – deed02392
    Jul 23, 2020 at 16:29

1 Answer 1

4
\$\begingroup\$

Review

  1. Python and recursion are not the best match, instead use loops

    It could even be done with list comprehension

    return [ip if ip not in exclude for ip in subnet]

  2. Alter your imports to use one of the two not both

    I suggest to use from ipaddress import IPv4Network because that seems to be only thing imported from the library.

  3. Use sets!

    Lists are O(N), while sets are O(1)!

    Secondly it's quite easy to subtract sets simply use set(c) = set(a) - set(b)

Example

from ipaddress import IPv4Network

exclude = set(IPv4Network('1.1.0.0/25')) | set(IPv4Network('1.1.0.128/26'))
net = set(IPv4Network('1.1.0.0/24'))

print(net - exclude)
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Lists can be O(1) per element as well, if you know they are sorted (which list(IPv4Network(...)) is), and use that fact to only do a single pass over each list. \$\endgroup\$
    – G. Sliepen
    Jul 24, 2020 at 14:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.