Необходимо объединить определенные значения в извлеченном списке в подсписки

#python #list #file #dictionary

#питон #Список #файл #словарь

Вопрос:

Я извлекаю этот блок текста из файла для преобразования в словарь:

 ACC210: Luther, Martin Spurgeon, Charles  CS121P: Bunyan, John Henry, Matthew Luther, Martin  CS132S: Calvin, John Knox, John Owen, John  

и это код, который я использовал, чтобы открыть его и создать два списка, чтобы я мог использовать их для создания словаря:

 with open("classes.txt") as file:  data = [line.strip() for line in file]  a = []  b = []  for x in data:  if ':' in x:  a.append(x)  else:  b.append(x)  

Списки выходят в виде

 ['ACC210:', 'CS121P:', 'CS132S:'] ['Luther, Martin', 'Spurgeon, Charles', '', 'Bunyan, John', 'Henry, Matthew', 'Luther, Martin', '', 'Calvin, John', 'Knox, John', 'Owen, John', '']  

Однако мне нужно, чтобы второй список выглядел так:

 [['Luther, Martin', 'Spurgeon, Charles'],['Bunyan, John', 'Henry, Matthew','Luther, Martin'], ['Calvin, John', 'Knox, John', 'Owen, John']]  

Как бы я это сделал?

Ответ №1:

Вы можете попробовать следующее:

 lst1, lst2 = [], [] with open('input.txt', 'r') as f:  for line in map(lambda x: x.rstrip('n'), f):  if ':' in line:  lst1.append(line)  lst2.append(names := [])  elif line:  names.append(line)  print(lst1) # ['ACC210:', 'CS121P:', 'CS132S:'] print(lst2) # [['Luther, Martin', 'Spurgeon, Charles'], ['Bunyan, John', 'Henry, Matthew', 'Luther, Martin'], ['Calvin, John', 'Knox, John', 'Owen, John']]  

Для этой строки lst2.append(names := []) требуется python 3.8 . Если эта строка не работает для вас, используйте:

 names = [] lst2.append(names)  

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

1. да, это прекрасно, спасибо!

Ответ №2:

Если вы пытаетесь сделать диктант, вы можете сделать:

 import re   di={} with open(fn) as f:  for k,v in re.findall(r'(^.*):([sS]*?)(?=^$|Z)', f.read(), flags=re.M):  di[k]=v.strip().splitlines()  gt;gt;gt; di {'ACC210': ['Luther, Martin', 'Spurgeon, Charles'], 'CS121P': ['Bunyan, John', 'Henry, Matthew', 'Luther, Martin'], 'CS132S': ['Calvin, John', 'Knox, John', 'Owen, John']}  

Если вам нужны два списка:

 import re   a,b=[],[] with open(fn) as f:  for k,v in re.findall(r'(^.*):([sS]*?)(?=^$|Z)', f.read(), flags=re.M):  a.append(k)  b.append(v.strip().splitlines())  gt;gt;gt; a ['ACC210', 'CS121P', 'CS132S'] gt;gt;gt; b [['Luther, Martin', 'Spurgeon, Charles'], ['Bunyan, John', 'Henry, Matthew', 'Luther, Martin'], ['Calvin, John', 'Knox, John', 'Owen, John']]  

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

 a,b=[],[] with open(fn) as f:  for k, sl in ((sl[0], sl[1:])   for sl in (e.splitlines()   for e in f.read().rstrip().split('nn'))):  a.append(k.rstrip(':'))  b.append(sl)  # same a,b  

Тем же методом вы можете напрямую создать диктант:

 with open(fn) as f:  di={sl[0]:sl[1:] for sl in (e.splitlines()   for e in f.read().rstrip().split('nn'))}  gt;gt;gt; di {'ACC210:': ['Luther, Martin', 'Spurgeon, Charles'], 'CS121P:': ['Bunyan, John', 'Henry, Matthew', 'Luther, Martin'], 'CS132S:': ['Calvin, John', 'Knox, John', 'Owen, John']}