我有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,第二个列表有30'000个子网。这需要花费大量时间来迭代。我知道这是实现这一目标的一种可怕方式,但我知道我总能改进。
任何人都可以建议我如何更好地解决这个问题?如何搜索和比较每个元素以缩短此脚本的运行时间?
以下是示例数据
[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
答案 0 :(得分:0)
1)显然它很慢因为OP有三个嵌套循环:两个级别的嵌套迭代(i,j)比CSV1文件,然后迭代 ipNetwork 。你应该像瘟疫一样避免深陷。
要测试CSV1中的成员资格,请先对CSV1进行第一次迭代以读取所有内容,然后将其存储为set
:
ips = [line[0] for line in CSV1.readlines()] # or whatever, using csv.reader
ips = set(ips)
事实上,Python的最新版本允许您直接生成集合(这称为生成器表达式)
ips = set(line[0] for line in CSV1.readlines())
现在你根本不需要j-iteration,因为你正在使用set
。您只需使用if ip in ...
测试成员资格
所以我们已经淘汰了三个嵌套循环中的一个。也许两个。
2)同样以便在测试ip in ipNetworks...
时获得性能提升,您可以使用正则表达式和/或分层ipAddress
类,例如允许将ipAddress('157.55.130')
与ipAddress('157.55.*.*)
进行比较。在比较IP时,请参阅SO上的许多现有重复项。您可以允许使用通配符*
和/或xxx
。
如果使用通配符并合并相邻地址,则应该能够将CSV1和ipNetwork长度分别压缩到9K以下; 30K。
查看许多现有的SO问题,例如: 1.使用正则表达式Python: Efficient way to compare ip addresses in a csv file 1.使用自定义类Compare IP List to another IP List or IP Range 1.与范围Checking if IP address lies within a given range
进行比较答案 1 :(得分:0)
这里有一些很棒的建议,它给了我很多东西。
我最终做的是通过IP订购两个列表。一旦我比较了一个排序的IP列表并寻找一个IP网络,它就在CIDR列表中,我将其设置为临时变量。很多IP都是连续的,因此接下来的几个IP也可能处于临时状态。
然后我基本上将搜索范围缩小到找到的CIDR的索引。因此,在每次迭代后,我的CIDR列表搜索都会减少。
它可能不是很漂亮或最优化但它可以工作。
一旦我对它进行了一些修饰,我将包括一个样本。