Я пытаюсь создать словарь с файлом, содержащим текст, на основе сопоставленного шаблона. Строки, содержащие key_str, должны стать ключами, а последующие строки, не соответствующие key_str, должны стать значениями и ассоциироваться с ключами в словаре. так что у меня работает код ниже: Но мне нужна помощь и получение
- лучшие практики и шаблон дизайна в моем случае
- Производительность в случае, если мой файл находится в ГБ
- Альтернативные / разные подходы без использования каких-либо модулей, а только грубая логика. например, не хочу использовать коллекции. для использования модуля python я могу задать другой вопрос, но здесь я просто хочу перейти к подходам с необработанной логикой.
Файл: file2dict.result-soa1
ml1
/var
/home
cpuml2
/var
/home
Выход
my_dict: {ml1: ['/var','/home'], cpuml2: ['/var','/home']}
Код:
import os
homedir = os.environ.get('HOME')
key_str = "ml"
my_dict = {}
val_list = []
key = ''
with open(homedir + '/backup/file2dict.result-soa1') as file2dict:
for line in file2dict:
words = line.split()
for aWord in words:
if key_str in aWord:
if key:
my_dict[key] = val_list
val_list = []
key = aWord
else:
key = aWord
else:
val_list.append(aWord)
my_dict[key] = val_list
print(my_dict)
1 ответ
Ваш код готов к хорошему началу, но вот несколько предложений по скромным улучшениям или способам упростить и прояснить ситуацию.
Встроенный pathlib библиотека часто является самым простым и надежным способом работы с путями к файлам.
Скрипты с жестко заданными путями к файлам обычно негибкие. Например, чтобы просмотреть ваш код, мне пришлось отредактировать его сразу же, потому что на моем компьютере отсутствует ваша структура каталогов. Во время собственной разработки и отладки сценария вы можете не захотеть каждый раз работать с реальным файлом (часто проще использовать крошечную реплику). Все это означает, что вам лучше использовать пути по умолчанию с опцией переопределения командной строки. Эта корректировка также дает вам хорошие перспективы на будущее: если потребности в сценарии увеличиваются, вы можете легко добавить поддержку дополнительных аргументов или параметров командной строки.
Я бы посоветовал вам принять проверенную временем передовую практику размещения почти всего основного кода внутри определений функций или классов. Это легко сделать, а большая изоляция ведет к увеличению гибкости. Например, в предлагаемых ниже изменениях, которые по-прежнему в значительной степени соответствуют исходному коду, алгоритмическая сложность синтаксического анализа была извлечена в узкоспециализированную функцию, которая ничего не знает о более серьезных проблемах программы. Ему не обязательно знать пути, чтение файлов и т. Д. Вместо этого он принимает любую итерацию, содержащую строки соответствующих данных. Это упрощает отладку и тестирование, потому что вы можете вызывать его отдельно, просто используя список строк.
Приведенные ниже правки также дают краткую иллюстрацию того, как даже довольно краткие комментарии могут добавить контекст и помочь читателю понять как цель, так и общую логику. Некоторые комментарии похожи на сообщения с указанием организации: например, «Настройка» или «Разбор». Они упрощают визуальное сканирование кода, чтобы сориентироваться. Другие комментарии могут помочь читателю, интуитивно объясняя суть алгоритма (например, два комментария во внутреннем цикле). Обратите внимание, что комментарии не имитируют код; скорее, они помогают его организовать и проливают дополнительный свет на него.
Как минимум, я бы посоветовал вам принять согласованные соглашения об именах переменных. Иногда вы следуете практике добавления суффиксов типа данных к именам; в других случаях нет. Я никогда не считал такую практику ценной, но мнения расходятся. Назвать переменные, функции и классы сложно, потому что часто существуют конкурирующие приоритеты: ясность, краткость, простота набора текста, легкость чтения, необходимость сравнивать / противопоставлять похожие вещи и так далее. В приведенных ниже изменениях некоторые из приведенных ниже имен являются обычными. Например, если мне не нужно одновременно открывать несколько файлов, я всегда использую fh для «дескриптора файла». То же самое для args в main() функция. Другие имена довольно ясны и понятны человеку: default, file_name, file_path, line, и word примеры в этом ведре. И другие имена менее сильны: например, data
и vals. В некоторых контекстах уместно универсальное имя (например, универсальная функция, которая выполняет общую операцию с некоторыми входными данными). В вашем случае я подозреваю, что существуют более содержательные имена, но их знаете только вы.
from sys import argv
from pathlib import Path
def main(args):
# Get file path to the input data file.
default="backup/file2dict.result-soa1"
file_name = args[0] if args else default
file_path = Path.home() / file_name
# Parse.
with open(file_path) as fh:
data = parse_data(fh)
# Report.
print(data)
def parse_data(lines):
# Setup.
data = {}
vals = []
key = None
marker="ml"
# Parse.
for line in lines:
for word in line.split():
if marker in word:
# Store current VALS; and setup new KEY and VALS.
if key:
data[key] = vals
vals = []
key = word
else:
# Or just store with current VALS.
vals.append(word)
# Wrap-up and return.
data[key] = vals
return data
if __name__ == '__main__':
main(argv[1:])
