Уменьшите длину списка, перебирая его элементы - PullRequest
0 голосов
/ 12 ноября 2018

Проблема: Есть 2 списка, один считается родительским, а другой дочерним. То, что я хочу сделать, это построить третий список на основе условия.

Текущее решение:

from netaddr import *

l1 = ['10.0.0.0/8', '172.16.0.0/16']
l2 =['10.10.10.10','172.16.15.0/24','10.20.10.0/24','13.1.1.0/24','15.10.10.0/24','172.16.16.0/25','10.10.11.11']

[ip1 for ip1 in l1 for ip2 in l2 if IPNetwork(ip2) in IPNetwork(ip1)]

Выход:

['10.0.0.0/8', '10.0.0.0/8', '10.0.0.0/8', '172.16.0.0/16', '172.16.0.0/16']

Приведенное выше понимание, на мой взгляд, не является оптимальным решением

Я ищу , чтобы найти способ, с помощью которого я мог бы повторно реализовать вышеупомянутое решение с дополнительным преимуществом удаления элементов (см. Ip2), которые сопоставляются с l2 в каждой итерации, таким образом, избегайте перепроверки эти элементы снова в следующей итерации

1 Ответ

0 голосов
/ 14 ноября 2018

Здесь решение со счетчиком и набором.

Кроме того, он определяет объекты IPNetwork только один раз, что является самой медленной операцией (стоит 50 мкс, когда n2 in n1 стоит всего 5 мкс).

from collections import Counter
cnt=Counter()
S2=set(IPNetwork(ad2) for ad2 in l2)
for ad1 in l1:
    n1=IPNetwork(ad1)
    found=set()
    for n2 in S2: 
        if n2 in n1:
            cnt[ad1]+=1
            found.add(n2)
    S2 -= found

Наконец cnt равно Counter({'10.0.0.0/8': 3, '172.16.0.0/16': 2}) и S2 равно {IPNetwork('13.1.1.0/24'), IPNetwork('15.10.10.0/24')}.

...