在 Python 中将文本文件的内容读入字典

Read contents of a text file into a Dictionary in Python

我有一个文本文件 (img.txt),其中的数据如下:

0 0.288281 0.618056 0.080729 0.473148
5 0.229427 0.604167 0.030729 0.039815
0 0.554427 0.024537 0.020313 0.041667
0 0.547135 0.018981 0.020313 0.034259

所以我想创建一个字典,将 .txt 文件作为键,将所有行作为值。有点像

dict={'img.txt':['class':0, 'x':0.288281, 'y':0.618056, 'height':0.080729, 'width':0.473148 ],
                ['class':5, 'x':0.229427, 'y':0.604167, 'height':0.030729, 'width':0.039815 ]}

有没有办法添加值的键(如 class、x、y 等)。同样出于某种原因,在读取文件时,我的代码忽略了 class 值(如 0,5 等)。这是我的代码:

import os
list_of_files = os.listdir('C:/Users/Lenovo/annotation/')
count =0
my_dict = {}
for file in list_of_files:
    if count < 20:
        with open(file) as f:
            items = [i.strip() for i in f.read().split(" ")]
            my_dict[file.replace(".txt", " ")] = items
    else:
        break
    count = count+1
print(my_dict)

这是我的输出:

{'img_ano (1) ': ['0', '0.288281', '0.618056', '0.080729', '0.473148\n5', '0.229427', '0.604167', '0.030729', '0.039815\n0', '0.554427', '0.024537', '0.020313', '0.041667\n0', '0.547135', '0.018981', '0.020313', '0.034259\n4', '0.533073', '0.488889', '0.022396', '0.077778\n4', '0.630469', '0.375926', '0.017188', '0.075926\n4', '0.132031', '0.431944', '0.019271', '0.065741\n4', '0.802083', '0.191204', '0.013542', '0.037963\n4', '0.823958', '0.175000', '0.012500', '0.038889\n4', '0.702083', '0.192130', '0.013542', '0.036111'],.......}

假设您在文件夹 C:/Users/Lenovo/annotation/ 中只有包含以下内容的文件 img_ano.txt:

0 0.288281 0.618056 0.080729 0.473148
5 0.229427 0.604167 0.030729 0.039815
0 0.554427 0.024537 0.020313 0.041667
0 0.547135 0.018981 0.020313 0.034259

您可以使用 for 循环创建具有所需结构的字典 my_dictcollections.<b>defaultdict</b>, str.<b>strip</b>,str.<b>split</b>, and pathlib.PurePath.<b>stem</b>:

import json
import pathlib
from collections import defaultdict

my_dict = defaultdict(list)
for txt_file_path in pathlib.Path("C:/Users/Lenovo/annotation/").glob("*.txt"):
    with open(txt_file_path, "r") as f:
        for line in f:
            class_val, x_val, y_val, height_val, width_val = line.strip().split()
            my_dict[txt_file_path.stem].append({
                "class": int(class_val),
                "x": float(x_val),
                "y": float(y_val),
                "height": float(height_val),
                "width": float(width_val)
            })

print(json.dumps(my_dict, indent=4))

输出:

{
    "img_ano": [
        {
            "class": 0,
            "x": 0.288281,
            "y": 0.618056,
            "height": 0.080729,
            "width": 0.473148
        },
        {
            "class": 5,
            "x": 0.229427,
            "y": 0.604167,
            "height": 0.030729,
            "width": 0.039815
        },
        {
            "class": 0,
            "x": 0.554427,
            "y": 0.024537,
            "height": 0.020313,
            "width": 0.041667
        },
        {
            "class": 0,
            "x": 0.547135,
            "y": 0.018981,
            "height": 0.020313,
            "width": 0.034259
        }
    ]
}

所以有人正确回答并解决了我的问题,但由于某种原因删除了答案。所以这里是提供的解决方案中的代码(我只修改了 运行 一个从文本文件列表中添加文件的循环):

    import os
    import json
    from collections import defaultdict
    list_of_files = os.listdir('C:/Users/Lenovo/annotation/')
    count =0
    

    my_dict = defaultdict(list)
    for file in list_of_files:
        if count < 20:
            with open(file) as f:
                for line in f:
                    class_val, x_val, y_val, height_val, width_val =                   line.strip().split()
                    my_dict[file].append({"class": class_val,"x": x_val,"y": y_val,"height": height_val,"width": width_val
    })
        
        else:
            break
        count = count+1
    print(json.dumps(my_dict, indent=4))

    
dictt = {}
dictt['img.txt'] = []
for file in list_of_files.split('\n'):
    dictt['img.txt'] =  dictt['img.txt'] + ['class:'+str(file.split(' ')[0]), 'x:'+str(file.split(' ')[1]), 'y:'+str(file.split(' ')[2]), 'height:'+str(file.split(' ')[3]), 'width:'+str(file.split(' ')[4])]

print(dictt)

>>> {'img.txt': ['class:0', 'x:0.288281', 'y:0.618056', 'height:0.080729', 'width:0.473148', 'class:5', 'x:0.229427', 'y:0.604167', 'height:0.030729', 'width:0.039815', 'class:0', 'x:0.554427', 'y:0.024537', 'height:0.020313', 'width:0.041667', 'class:0', 'x:0.547135', 'y:0.018981', 'height:0.020313', 'width:0.034259']}
 

您实际上可以将其作为 csv 文件读取。这是一个 space 分隔值文件。 Python 提供了一个非常好的 csv 解析模块 (csv)。

我将字段名称和分隔符设置为格式定义,这将是静态的。

如您所见,您可以将列表推导式和字典推导式结合起来,只需几行代码,无需任何中间变量,即可实现您想要的结果。

然后,如果只处理“.txt”文件,您可以使用 globbing。 使用python的pathlib,使用Path().glob()会return个Path对象,这样有两个好处:

  • 一个open()方法(相当于open(filename))
  • 一个词干方法,将为您过滤掉扩展名

最后,您可以使用csv's DictReader class 直接return 一个您想要的形式的字典。只需指定字段名(这将是你的字典的键)和一个 ' ' (space) 作为分隔符,这样 csv 模块就会知道如何读取文件。

为方便起见,我将其设置为一个函数,您可以使用您认为必要的任何路径和 glob 调用。

import csv
from pathlib import Path
CSVFMT = dict(fieldnames=['class', 'x', 'y', 'height', 'width'], delimiter=' ')


def process_path(path, pattern):
    return {
        fop.stem: [dict(a) for a in csv.DictReader(fop.open(), **CSVFMT)]
        for fop in Path(path).glob(pattern)
    }


process_path('C:/Users/Lenovo/annotation/', '*.txt')