我有一个巨大的网络列表(称为a),我需要检查这些网络的地址是否存在于另一个网络列表(称为B)中:
两份清单的格式如下:
列表A
1.2.3.4
145.2.3.0/24
6.5.0.0/16
3.4.1.0/24
列表B
^{pr2}$两个列表A∩B:等交集的预期结果
1.2.3.4
3.4.1.0/24
我的第一个测试很天真:
此方法适用于小列表。但是,这种解决方案不适合于数千个网络(即几百万个IP地址),因为I don't have enough memory。此外,该解决方案不适用于IPv6网络。在
怎样做两个列表的交集最有效?
另外:我还要在列表A和其他列表B之间重复这一点:A∩C,A∩D等
我愿意接受所有的建议,即使是pig:-)
解决方案:
def chunks(l, n):
for i in xrange(0, len(l), n):
yield l[i:i+n]
res = []
for chunk_a in chunks(A, 1000):
for chunk_b in chunks(B, 1000):
C = IPSet(chunk_a) & IPSet(chunk_b)
if C > IPSet([]):
res.append(C)
好吧,如果你对猪敞开心扉,那么没什么比这更容易的了。它不会遇到内存不足的问题,并且使用
JOIN
进行交集非常简单:完成了。在
这里有一种基于实现IP地址/网络集的
netaddr
包的可能性。在首先,假设A=A1∪A2和B=B1∪B2,那么A∩B=(A1∩B1)∪(A1∩B2)∪(A2∩B1)∪(A2∩B2)。在
因此,您可以将列表分解为多个小集合,并使用上面的方法递增地计算交集。例如:
但是考虑到,当使用IPSet时,您不需要列出所有的地址,您可能能够执行交集而不必求助于将列表分解为小集合。在
更新:在一台拥有4GB内存的笔记本电脑上,由5000个随机定义的网络(长度8到24位)组成的两个列表的交集只需几秒钟:
列出两个IP地址列表:
^{pr2}$使它们相交:
相关问题 更多 >
编程相关推荐