在文件中输入列表项

瓦赛

下午好,我有多个IP和MAC列表,任意长度的列表

A = [['10.0.0.1','00:4C:3S:**:**:**', 0], ['10.0.0.2', '00:5C:4S:**:**:**', 0], [....], [....]]

我想检查这个MAC是否在oui文件中:

E043DB   (base 16)   Shenzhen
2405f5   (base 16)   Integrated
3CD92B   (base 16) Hewlett Packard
...

如果列表中的 MAC 在文件中,则将制造商名称写为 3 个列表项。我正在尝试这样做,结果只检查第一个元素,未检查其余元素,我该怎么做,请告诉我?

f = open('oui.txt', 'r')
for values in A:
    for line in f.readlines():
        if values[1][0:8].replace(':','') in line:
            values[2]=(line.split('(base 16)')[1].strip())
f.close()
print (A)

并得到答案:

A = [['10.0.0.1','00:4C:3S:**:**:**', 'Firm Name'], ['10.0.0.2', '00:5C:4S:**:**:**', 0], [....], [....]]
惊骇

问题

考虑代码的“形状”:

f = open('a file')
for values in [ 'some list' ]:
    for line in f.readlines():

你的两个循环正在这样做:

Start with first value in list
Read all lines remaining in file object f
Move to next value in list
Read all lines remaining in file object f

除了第一次告诉它“读取剩余的所有行”时,它会这样做。

因此,除非您有某种方法将更多行放入 f(这可能发生在像 stdin 这样的异步文件中!),否则您将获得一次“良好”的文件传递,然后文件对象的每个后续传递都将指向文件的结尾,所以你什么也得不到。

一个解法

当您处理一个文件时,您只想处理一次。与其他操作相比,文件 I/O 是昂贵的。所以你可以选择 (a) 将整个文件读入内存,然后做任何你想做的事情,因为它不再是一个文件;或 (b) 仅扫描一次。

如果您选择只扫描一次,简单的解决方案就是反转两个 for 循环。而不是这样做:

for item in list:
    for line in file:

改为这样做:

for line in file:
    for item in list:

而且很快!您现在只读取文件一次。

其他注意事项

如果我查看您的代码和示例,您似乎正在尝试对特定键进行精确匹配您可以修剪列表中的 MAC 地址以根据制造商 ID 检查它们。

这向我表明,您可能拥有比制造商更多的列表值(源 MAC 地址)。因此,也许您应该考虑将 tile 的内容读入内存,而不是一次处理一行。

将文件保存在内存中后,请考虑构建合适的字典。您有一个密钥(MAC 前缀)和一个值(制造商)。所以构建类似的东西:

for line in f:
    mac = line.split('(base 16)')[0].strip()
    mfg = line.split('(base 16)')[1].strip()
    mac_to_mfg[mac] = mfg

然后,您可以遍历源地址并使用 dict 的 O(1) 查找对您有利:

for src in A:
    prefix = src[1][:8].replace(':', '')
    if prefix in mac_to_mfg:
        # etc...

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章