Python 优化三个嵌套循环,循环遍历2个IP地址数据帧?

Python 优化三个嵌套循环,循环遍历2个IP地址数据帧?,python,python-3.x,pandas,csv,ip-address,Python,Python 3.x,Pandas,Csv,Ip Address,我有2个CSV文件。 一个有主机名和IP的。 第二个包含IP信息(网络掩码、Cidr、子网名称等) 我目前的情况如下 for i, ipAddress in CSV1: for j, ipNetwork in CSV2: if ipAddress in ipNetwork: append ipNetwork['Subnet Name'] 不幸的是,第一个csv有9000个IP,第二个列表有30000个子网。这需要花费大

我有2个CSV文件。 一个有主机名和IP的。 第二个包含IP信息(网络掩码、Cidr、子网名称等)

我目前的情况如下

for i, ipAddress in CSV1:
       for j, ipNetwork in CSV2:
             if ipAddress in ipNetwork:
                  append ipNetwork['Subnet Name']
不幸的是,第一个csv有9000个IP,第二个列表有30000个子网。这需要花费大量的时间进行迭代。我知道这是一个可怕的实施方式,但我知道我可以随时提高

有人能告诉我如何更好地解决这个问题吗?如何搜索和比较每个脚本中的元素以缩短此脚本的运行时间

下面是示例数据

[CSV 1 - Sample IP]

IP Address
144.196.86.89
56.144.25.138
3.16.101.238
123.18.128.50
19.22.2.124
78.88.241.163
144.44.200.20
27.215.172.218
124.90.163.19

[CSV 2 - Sample Subnet Information]

address netmask Company Subnet Name Compartment Type    cidr
10.2.1.0    255.255.255.0   UPS UPS Site 1  Desktop 10.2.1.0/24
10.2.2.0    255.255.255.0   UPS UPS Site 2  Desktop 10.2.2.0/24
10.2.3.0    255.255.255.0   UPS UPS Site 3  Desktop 10.2.3.0/24
10.2.4.0    255.255.255.0   UPS UPS Site 4  Desktop 10.2.4.0/24
10.2.5.0    255.255.255.0   UPS UPS Site 5  Desktop 10.2.5.0/24
10.2.6.0    255.255.255.0   UPS UPS Site 6  Desktop 10.2.6.0/24
10.2.7.0    255.255.255.0   UPS UPS Site 7  Desktop 10.2.7.0/24
10.2.8.0    255.255.255.0   UPS UPS Site 8  Desktop 10.2.8.0/24
10.2.10.0   255.255.254.0   UPS UPS Site 9  Desktop 10.2.10.0/23
10.2.12.0   255.255.255.0   UPS UPS Site 10 Desktop 10.2.12.0/24
10.2.13.0   255.255.255.0   UPS UPS Site 11 Desktop 10.2.13.0/24
1) 很明显,它很慢,因为OP有三个嵌套循环:CSV1文件上的两级嵌套迭代(i,j),然后是ipNetwork上的迭代。你应该避免像瘟疫一样的深巢

要测试CSV1中的成员资格,请在CSV1上进行第一次迭代,以读取所有IP,并存储为

ips = [line[0] for line in CSV1.readlines()] # or whatever, using csv.reader
ips = set(ips)
事实上,Python的最新版本允许您直接生成集合(这称为生成器表达式)

现在您根本不需要j迭代,因为您使用的是
。如果ip位于…,您只需使用
测试成员身份。
我们已经消除了三个嵌套循环中的一个。也许两个

2) 另外,为了在测试ipNetworks中的ip时获得性能提升…,您可以使用正则表达式和/或分层的
ipAddress
类,例如允许将
ipAddress('157.55.130')
ipAddress('157.55.*.*)
进行比较。查看许多现有的副本,等等。您可以允许使用通配符
*
和/或
xxx
。 如果您使用通配符并合并相邻地址,您应该能够将CSV1和ipNetwork长度压缩到9K以下;分别为30K

请参阅许多现有的SO问题,例如: 1.使用正则表达式 1.使用自定义类
1.与一系列建议相比

这里有一些很好的建议,让我看了很多

我最后做的是按IP对两个列表进行排序。当我比较IP的排序列表并查找它在CIDR列表中的IP网络时,我会将其设置为临时变量。很多IP都是连续的,所以接下来的几个IP也可能是临时IP

然后我基本上将搜索范围缩小到找到的CIDR的索引。因此,每次迭代之后,我的CIDR列表搜索都会减少

它可能不漂亮,也不是最优化的,但它可以工作


一旦我对它稍加润色,我会提供一个样本。

你能分享一些数据吗?请看。@jpp我不明白你为什么否决了他的问题。我认为它有足够的信息来保证一个解决方案或至少是一个想法。我建议的一个建议是将IP地址和子网(假设它们都表示为字符串)强制转换为整数或字节。原因是字符串是不可变的,并且字符串比较是一项昂贵的操作。你可能会有一些想法主要的问题是我不知道为什么你现在的方法这么慢。您是否使用本机Python
open
<代码>csv模块<代码>熊猫?我们如何知道我们提供的解决方案是否是您当前使用的慢解决方案?@Plisken,那么什么是
CSV1
/
CSV2
?请提供一个答案。基本上,这里所问的问题是几个现有问题的重复,但它们非常混乱,几乎不可能找到并引用它们。因此,我没有再次回答,而是将精力投入到:。我还列出了一些可能的规范。这个主题非常混乱,需要清理志愿者和连贯的标签。
ips = set(line[0] for line in CSV1.readlines())