Проблемы с организацией данных из текстового файла в словарь

#python #dictionary #text

#python #словарь #текст

Вопрос:

Я новичок python и работаю над проектом, в котором мне нужно организовать данные из .txt файла в dictionary (ключевым значением словаря должно быть полное имя человека, в то время как другие данные — это его значение в форме словаря) dictionary , внутри dictionary которого должно быть —

  • item
  • location
  • date of purchase
  • remarks
  • salespeople

.txt Документ выглядит следующим образом:

 Jimothy Donovan
Guitar
California
20.6.2018
The frame is broken
ENDREMARK
Hank Pym
Daniel Bennet
X
Isaac Newton
Hourglass
San Jose
12.8.2019
The hourglass is not accurate anymore
would like replacement
ENDREMARK
Daniel Bennet
Ethan Cole
X
 

Код выглядит следующим образом:

 def process_data(file: TextIO) -> Dict:
    CustomerDataDict = {}
    lines = file.readline().strip()
    x = 0
    for line in file:
        key = lines[x].strip()
        CustomerDataDict[key[0]] = lines[x 1].strip()
        CustomerDataDict[key[1]] = lines[x 2].strip()
        CustomerDateDict[key[2]] = lines[x 3].strip()

        start = lines.index('ENDREMARKn')
        list_remark = lines[3:start]
        full_remark = ''
        for n in list_remark:
            full_remark  = n
        CustomerDataDict[key[3]] = full_remark

        end = lines.index('Xn')
        salesppl_list = lines[start   1:end]
        salespeople = []
        for name in salesppl_list:
            following.append(name.strip())
       CustomerDataDict[key[4]] = salespeople

        x = end   1

    return CustomerDataDict
 

Формат Dictionary должен быть:

 {username: 
    {'item':itemname, 
     'location':location, 
     'date-of-purchase': DATE, 
     'remarks':remarks, 
     'salespeople': {names of salespeople}
    }
}
 

Любая помощь приветствуется!

Ответ №1:

Вы можете использовать итератор для текстовых строк и продвигаться по нему на основе вашей структуры:

 text = """Jimothy Donovan
Guitar
California
20.6.2018
The frame is broken
ENDREMARK
Hank Pym
Daniel Bennet
X
Isaac Newton
Hourglass
San Jose
12.8.2019
The hourglass is not accurate anymore
would like replacement
ENDREMARK
Daniel Bennet
Ethan Cole
X"""
 

 lines = iter(text.split("n"))    # create iterator (get data from the file)

customerData = dict()
while True:
    username = next(lines,None)
    if not username: break
    customerData[username]        = userData    = dict()
    userData["item"]              = next(lines)
    userData["location"]          = next(lines)
    userData["date-of-purchase"]  = next(lines)
    userData["remarks"]           = remarks     = list()
    userData["salespeople"]       = salespeople = set()
    while True:
        remark = next(lines)
        if remark == "ENDREMARK": break
        remarks.append(remark)
    while True:
        salesperson = next(lines)
        if salesperson == "X": break
        salespeople.add(salesperson)
 

Это приведет к созданию желаемого словаря, если данные соответствуют ожидаемой структуре.

 print(customerData)
    
{'Jimothy Donovan':
     {'item': 'Guitar',
      'location': 'California',
      'date-of-purchase': '20.6.2018',
      'remarks': ['The frame is broken'],
      'salespeople': {'Daniel Bennet', 'Hank Pym'}},
 'Isaac Newton':
     {'item': 'Hourglass',
      'location': 'San Jose',
      'date-of-purchase': '12.8.2019',
      'remarks': ['The hourglass is not accurate anymore', 'would like replacement'],
      'salespeople': {'Ethan Cole', 'Daniel Bennet'}}
}
 

[РЕДАКТИРОВАТЬ] альтернативная версия без использования операторов break (в конце концов, не так уж и плохо):

 customerData = dict()
username = next(lines,None)
while username is not None:
    customerData[username]        = userData    = dict()
    userData["item"]              = next(lines)
    userData["location"]          = next(lines)
    userData["date-of-purchase"]  = next(lines)
    userData["remarks"]           = remarks     = list()
    userData["salespeople"]       = salespeople = set()
    remark = next(lines) 
    while remark != "ENDREMARK":
        remarks.append(remark)
        remark = next(lines)
    salesperson = next(lines)
    while salesperson != "X":
        salespeople.add(salesperson)
        salesperson = next(lines)
    username = next(lines,None)
 

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

1. Да, но это делает код более повторяющимся и громоздким. Что вам нужно сделать, это получить следующее значение один раз вне цикла (например username = next(lines,None) , и снова в конце цикла. Тогда ваш цикл может быть while username is not None: . То же самое относится к циклам комментариев и продавцов.