Запись элемента списка в файл - PullRequest
0 голосов
/ 22 ноября 2018

Добрый день, у меня есть несколько списков 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], [....], [....]]

Ответы [ 2 ]

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

Проблема

Рассмотрите «форму» вашего кода:

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!), Вы получите один «хороший» проход по файлу, а затем каждый последующий проходобъект файла будет указывать на конец файла, поэтому вы ничего не получите.

A Решение

Когда вы имеете дело с файлом, вы хотите толькообработайте это один раз.Файловый ввод / вывод дорог по сравнению с другими операциями.Таким образом, вы можете выбрать (а) считывание всего файла в память и делать все, что захотите, поскольку это уже не файл;или (b) сканировать его только один раз.

Если вы решите сканировать его только один раз, простое решение - просто инвертировать два цикла for.Вместо этого:

for item in list:
    for line in file:

Сделайте это вместо:

for line in file:
    for item in list:

И presto!Теперь вы читаете файл только один раз.

Другие вопросы

Если я смотрю на ваш код и ваши примеры, кажется, что вы пытаетесь получить точное совпадение на конкретном ключе.Вы сокращаете MAC-адреса в своем списке, чтобы сравнить их с идентификаторами производителя.

Это наводит на мысль, что у вас вполне может быть много, гораздо больше значений списка (исходных MAC-адресов), чем у производителей.Поэтому, возможно, вам следует подумать о том, чтобы прочитать содержимое тайла в память, а не обрабатывать его по одной строке за раз.

Как только у вас будет файл в памяти, подумайте о создании правильного словаря.У вас есть ключ (префикс 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...
0 голосов
/ 22 ноября 2018

Проблема в том, что вы изменили порядок циклов.Обычно это не такая большая проблема, но когда рабочие объекты, которые потребляются (например, объект файла IO), содержимое больше не будет генерировать после его итерации.

Вам нужно будет выполнить итерациюСначала lines, а затем в каждом lines итерируйте по A, чтобы проверить значения:

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

print (A)

Обратите внимание, что я изменил открытие вашего файла для использования with диспетчера контекста вместо этого, если в вашем коде существует блок with, он автоматически close() файл для вас.Рекомендуется вручную open файл, так как вы можете забыть close() его после.

...