首页 > 解决方案 > 如何将文本文件的多行作为字典中键的值(在元组中)?

问题描述

我正在尝试读取一个文本文件,然后使用该文件中的数据创建一个字典。文本的一个例子是:

100
Mulan
300, 500
200, 400

200
Ariel
100, 500
500

300
Jasmine
500
500, 100

400
Elsa
100, 500


500
Belle
200, 300
100, 200, 300, 400

我需要将第一行作为字典的键,将第二、第三和第四行作为该键的值。

到目前为止,我的代码如下所示:

`file = open(file_name,"r")
d = {}
for line in file.readlines():
    line = line.split()
    if not line:
        continue
    d[line[0]] = line[1:]
return d`

但这会返回一些奇怪的东西:

{'100': [], 'Mulan': [], '300,': ['500'], '200,': ['300'], '200': [], 'Ariel': [], '100,': ['200,', '300,', '400'], '500': [], '300': [], 'Jasmine': [], '500,': ['100'], '400': [], 'Elsa': [], 'Belle': []}

显然,该函数将每行的第一个值作为键,这不是我想要的。我需要输出如下所示:

{100: ('Mulan', [300, 500], [200, 400]), 
200: ('Ariel', [100, 500], [500]), 
300: ('Jasmine', [500], [500, 100]), 
400: ('Elsa', [100, 500], []), 
500: ('Belle', [200, 300], [100, 200, 300, 400])}

谁能帮我弄清楚如何做到这一点,或者特别是如何从文本文件中获取多行以用作我的字典中的值?

标签: pythonpython-3.x

解决方案


选项1

查看您的示例,名称后似乎必须有两个列表。如果第二个是空的,你想在那里有一个空列表。因此,您已经在数据上强制使用了这种“5 行定义字典条目”的结构。阅读时不妨使用它:

from pprint import pprint

with open('data.txt', 'r') as F:
    lines = [line.replace('\n','') for line in F.readlines()]


n = len(lines)
d = 5                   # number of lines for one entry in the file

if not n%d==0:
    for i in range(d-n%d):
        lines.append('')    

result = {}
for i, line in enumerate(lines):
    if   i%5==0: key  = int(line)
    elif i%5==1: name = line.rstrip()
    elif i%5==2: 
        if line=='': num1 = []
        else: num1 = [int(x) for x in line.replace(' ','').split(',')]
    elif i%5==3:
        if line=='': num2 = []
        else: num2 = [int(x) for x in line.replace(' ','').split(',')]  
    elif i%5==4: result[key] = (name, num1, num2)

pprint(result)

这正是您想要的结果。

{100: ('Mulan', [300, 500], [200, 400]),
 200: ('Ariel', [100, 500], [500]),
 300: ('Jasmine', [500], [500, 100]),
 400: ('Elsa', [100, 500], []),
 500: ('Belle', [200, 300], [100, 200, 300, 400])}

“if not n%d==0:”部分添加空行,直到总数为 5 的倍数。这样添加“belle”条目即使很难,数据文件中只有 24 行。

选项 2

如果你真的不需要那个空列表,你可以从这里开始工作:

with open('data.txt', 'r') as F:
    lines = F.readlines()


long_line = ''.join([x.replace(' ','') for x in lines])
split     = [x.lstrip().split('\n') for x in long_line.split('\n\n')]


result    = {}
for e in split:
    result[int(e[0])] = (e[1], e[2:])


for key in sorted(result.keys()):
    print(key, result[key])

输出:

100 ('Mulan', ['300,500', '200,400'])
200 ('Ariel', ['100,500', '500'])
300 ('Jasmine', ['500', '500,100'])
400 ('Elsa', ['100,500'])
500 ('Belle', ['200,300'])

我知道这不是你的输出。但正如我所说:如果这些空列表不重要,你可以从这里开始工作。


推荐阅读