首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何解析文本文件并将行保存为键值和值列表

如何解析文本文件并将行保存为键值和值列表
EN

Stack Overflow用户
提问于 2019-05-02 09:46:22
回答 2查看 196关注 0票数 0

我试图解析许多".txt“文件,并将一些行作为键存储,另一些作为值存储在dict中。方法应该尽可能抽象,因为跨文件的总体文件结构是相同的,但是--有些记录可能有较少或更多的字段,而相同的字段在不同的记录中可能有较少或更多的行。

文本文件的格式与此类似,但通常带有或多或少的属性:

代码语言:javascript
复制
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

每一行结尾都是‘:“应该是一个键,下面的一行(或者下面的行,您可以看到)是该键的值列表。

预期产出:

代码语言:javascript
复制
{'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代码:

代码语言:javascript
复制
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))

我发现了一个错误:

代码语言:javascript
复制
IndexError: list index out of range

由此产生的dict:

代码语言:javascript
复制
{'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']}

结果是乱七八糟的,很可能是块里的什么东西造成的:

代码语言:javascript
复制
else:
    if len(values) > 0 and lines[i] in values[-1]:
        print({f'string {lines[i]}} already in [values], skipping')
        i+=1

如有任何帮助,将不胜感激,谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-02 10:01:55

以下是一些应该解决的问题:

代码语言:javascript
复制
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)

输出

代码语言:javascript
复制
{'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']}
票数 2
EN

Stack Overflow用户

发布于 2019-05-02 10:15:19

作为一种良好的实践,您应该避免在“索引”上循环,而应该使用dict理解和for-each循环:

代码语言:javascript
复制
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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55949733

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档