我正在尝试解析许多“ .txt”文件,并将某些行作为键存储,而另一些行作为值存储在字典中。
方法应尽可能抽象,因为整个文件的文件结构是相同的,但某些记录可以具有比其他记录更少或更多的字段,而同一记录可以具有更少或更多的行在不同的记录中。
文本文件格式如下,但通常具有或多或少的属性:
Autore principale:
Christie, Agatha
Titolo:
La mia vita / Agatha Christie ; traduzione di Maria Giulia Castagnone
Pubblicazione:
Milano : Oscar Mondadori, 1995
Descrizione fisica:
636 p. ; 20 cm.
Collezione:
Oscar narrativa ; 1563
Oscar scrittori moderni
Titolo uniforme:
An autobiography | Christie, Agatha
Numeri:
[ISBN] 978-88-04-52225-6 9. rist. 2013
Nomi:
Christie, Agatha
[Traduttore] Castagnone, Mariagiulia
Soggetti:
Christie, Agatha
Classificazione Dewey:
823.912 (19.) NARRATIVA INGLESE. 1900-1945
Lingua di pubblicazione:
ita
Paese di pubblicazione:
IT
Codice identificativo:
IT\ICCU\LIA\0962595
每行以':'结尾的行应该是一个键,而下一个(有时也可以是以下一个,如您所见)是一个值列表那个钥匙。
预期输出:
{'Autore principale:': ['Christie, Agatha'],
'Titolo:': ['\x88La \x89mia vita / Agatha Christie ; traduzione di Maria Giulia Castagnone'],
'Pubblicazione:': ['Milano : Oscar Mondadori, 1995'],
'Descrizione fisica:': ['636 p. ; 20 cm.'],
'Collezione:': ['Oscar narrativa ; 1563', 'Oscar scrittori moderni'],
'Titolo uniforme:': ['\x88An \x89autobiography | Christie, Agatha'],
'Numeri:': ['[ISBN] 978-88-04-52225-6 9. rist. 2013'],
'Nomi:': ['Christie, Agatha'],
...
...}
到目前为止,我已经来到了这个python代码:
with open('file.txt', 'r', encoding='utf-8', errors='ignore') as f:
lines = [line.strip() for line in f.readlines()]
record_keys = [elem for elem in lines if elem.endswith(':')]
# here comes the loop:
length = len(lines)
i = 0
values = []
while i < length:
if lines[i] in record_keys:
current_key = record_keys.index(lines[i])
i+=1
else:
if lines[i] == lines[-1]:
val = [i for i in lines[lines.index(lines[i]):]]
values.append(val)
i+=1
else:
if len(values) > 0 and lines[i] in values[-1]:
print({f'string {lines[i]}} already in [values], skipping')
i+=1
else:
next_key = record_keys[current_key+1]
val = [i for i in lines[lines.index(lines[i]):lines.index(next_key)]]
values.append(val)
i+=1
# dict from zip object
isbn_dict = dict(zip(record_keys, values))
我收到此错误:
IndexError: list index out of range
结果字典:
{'Autore principale:': ['Christie, Agatha'],
'Titolo:': ['\x88La \x89mia vita / Agatha Christie ; traduzione di Maria Giulia Castagnone'],
'Pubblicazione:': ['Milano : Oscar Mondadori, 1995'],
'Descrizione fisica:': ['636 p. ; 20 cm.'],
'Collezione:': ['Oscar narrativa ; 1563', 'Oscar scrittori moderni'],
'Titolo uniforme:': ['\x88An \x89autobiography | Christie, Agatha'],
'Numeri:': ['[ISBN] 978-88-04-52225-6 9. rist. 2013'],
'Nomi:': ['Christie, Agatha',
'Titolo:',
'\x88La \x89mia vita / Agatha Christie ; traduzione di Maria Giulia Castagnone',
'Pubblicazione:',
'Milano : Oscar Mondadori, 1995',
'Descrizione fisica:',
'636 p. ; 20 cm.',
'Collezione:',
'Oscar narrativa ; 1563',
'Oscar scrittori moderni',
'Titolo uniforme:',
'\x88An \x89autobiography | Christie, Agatha',
'Numeri:',
'[ISBN] 978-88-04-52225-6 9. rist. 2013',
'Nomi:',
'Christie, Agatha',
'[Traduttore] Castagnone, Mariagiulia'],
'Soggetti:': ['823.912 (19.) NARRATIVA INGLESE. 1900-1945'],
'Classificazione Dewey:': ['ita'],
'Lingua di pubblicazione:': ['IT'],
'Paese di pubblicazione:': ['IT\\ICCU\\LIA\\0962595']}
结果是一团糟,可能是由块中的某物引起的:
else:
if len(values) > 0 and lines[i] in values[-1]:
print({f'string {lines[i]}} already in [values], skipping')
i+=1
任何帮助将不胜感激,谢谢
答案 0 :(得分:2)
这是应该解决的问题:
with open('t6.txt', 'r', encoding='utf-8', errors='ignore') as f:
lines = [line.strip() for line in f.readlines()]
d = {}
keys = []
vals = []
for line in lines:
if line.endswith(':'):
keys.append(line)
else:
vals.append(line)
for k in keys[:-1]:
d[k] = lines[lines.index(k)+1:lines.index(keys[keys.index(k)+1])]
print(d)
输出:
{'Autore principale:': ['Christie, Agatha'],
'Titolo:': ['La mia vita / Agatha Christie ; traduzione di Maria Giulia Castagnone'],
'Pubblicazione:': ['Milano : Oscar Mondadori, 1995'],
'Descrizione fisica:': ['636 p. ; 20 cm.'],
'Collezione:': ['Oscar narrativa ; 1563', 'Oscar scrittori moderni'],
'Titolo uniforme:': ['An autobiography | Christie, Agatha'],
'Numeri:': ['[ISBN] 978-88-04-52225-6 9. rist. 2013'],
'Nomi:': ['Christie, Agatha', '[Traduttore] Castagnone, Mariagiulia'],
'Soggetti:': ['Christie, Agatha'],
'Classificazione Dewey:': ['823.912 (19.) NARRATIVA INGLESE. 1900-1945'],
'Lingua di pubblicazione:': ['ita'],
'Paese di pubblicazione:': ['IT']}
答案 1 :(得分:0)
作为一种好的做法,应避免循环“索引”,而应使用dict理解和for-each循环:
with open('file.txt', 'r', encoding='utf-8', errors='ignore') as f:
lines = [line.strip() for line in f.readlines()]
record_keys = { elem for elem in lines if elem.endswith(':') } # a set
isbn_dict = { elem : set() for elem in record_keys } # a dict of sets
current_key = None
for line in lines:
if line in record_keys:
current_key = line
else:
isbn_dict[current_key].add(line)