Получение файла со строками и превращение их в словарь со списками

#python

Вопрос:

моя проблема в том, что я хочу прочитать файл с несколькими строками, например:

 be:was, were I:you Tom  

Теперь я хочу превратить первый элемент (перед»:») в ключ диктанта, а все, что следует за»:», — в список. Каждая запись в списке разделяется символом ‘,’

Так что это должно выглядеть так:

 words_dict = {"be" : ["was", "were"], "I" : ["you"], "Tom" : []}  

Я придумал что-то вроде этого:

 with open(words, 'r') as file:  for line in file:  words = line.strip().split(':')  

Я не знаю, правильный ли это подход и что делать дальше.

Комментарии:

1. Вы находитесь на правильном пути, но отметьте maxsplit опцию включенной split . Сначала я бы разделил : с maxsplit, установленным на 1; первая часть-это ваш ключ словаря, а затем вторую часть лучше всего разделить re.split с помощью разделителя, такого как ',s*' (запятая, за которой следует любое количество пробелов), чтобы получить список, который является значением словаря.

2. И вам нужно будет обработать отсутствие : в строке как особый случай, когда line.split(':', 1) возвращается список из одного элемента вместо списка из двух элементов.

Ответ №1:

возможно, что-то вроде

 with open(words, 'r') as file:  for line in file.readlines(1024):  split = line.removesuffix('n').split(':', maxsplit=1)   if len(split) == 2:  vals = [val.strip() for val in split[1].split(',')]  else: # : not found in line  vals = []   d[split[0]] = vals  

Если вы сможете очистить данные, чтобы всегда гарантировать, что : после ключа есть, цикл может быть значительно упрощен;

 with open(words, 'r') as file:  for line in file.readlines(1024):  key, value = line.removesuffix('n').split(':', maxsplit=1)  d[key] = [val.strip() for val in value.split(',')]  

Комментарии:

1. если бы вы могли очистить данные, чтобы они всегда были : у вас (например Tom: ), вы могли бы немного очистить этот код, устранив необходимость if len(split) != 2 проверки, и вы могли бы просто сделать key, value = line.split(':', maxsplit=1)

2. Код, по-моему, выглядит нормально. Возможно, вопрос о том, следует ли читать весь файл сразу, является спорным, в зависимости от требований к памяти. Вы могли бы использовать понимание списка vals , но это не важно.

3. улучшил понимание списка и добавил улучшенный случай к моему ответу, и да, @alani, вы правы, память, возможно, может быть проблемой.

4. Это выглядит прекрасно. Один из способов справиться со случайными строками без двоеточия-поймать любое ValueError место, где вы распаковываете line.split(...) вывод.

5. Улучшен мой код, чтобы устранить возможную проблему с памятью в случае очень большого файла.

Ответ №2:

Сначала вы должны разделить строку, ':' чтобы получить ключи и остальную часть строки (если она есть), которые позже станут значениями. Затем разделите значения ',' и отфильтруйте их, если они не пусты после удаления.

Попробуй вот это:

 d = {} with open(words) as f:  for line in f:  key, *values = line.strip().split(':', maxsplit=1)  values = ''.join(values)  values = [w for word in values.split(',') if (w := word.strip())]  d[key] = values print(d)  

выход:

 {'be': ['was', 'were'], 'I': ['you'], 'Tom': []}  

Обратите внимание, что это работает, потому что: во-первых, метод «join» не вызовет исключения для пустых итераций, во-вторых, «split» также не жалуется на пустые строки.

Ответ №3:

Вы должны быть в состоянии использовать понимание словаря:

 with open(words, 'r') as file:  words = {(l:=s.rstrip('n').split(':'))[0]:l[1].split(', ') if len(l)gt;1 else []  for s in file}  

Комментарии:

1. В списке есть дополнительные 'n' пункты.

2. Ты прав @SorousH, я просто сделал это на макушке, забыл раздеться 😉

Ответ №4:

Краткое решение:

 data = {} with open('words.txt', 'r') as file:  for line in file.readlines():  key, *value = line.strip().split(':')  data[key] = list(filter(None, [i.strip() for i in ','.join(value).split(',')])) print(data)  

Выход:

 {'be': ['was', 'were'], 'I': ['you'], 'Tom': []}  

Комментарии:

1. Вы не делаете разделение на запятые, которое требуется.

2. «было» и «были» должны быть 2 отдельными пунктами внутри списка

3. @pigeonburger Эмм на самом деле нет, перед этим есть дополнительное место ' were' . (Также не забудьте обновить выходные данные)

4. ТЕПЕРЬ я это исправил. у-у-у

5. @pigeonburger, я думаю, тебе стоит проверить это еще раз