【问题标题】:Read contents of a text file into a Dictionary in Python在 Python 中将文本文件的内容读入字典
【发布时间】:2020-11-25 18:51:28
【问题描述】:

我有一个文本文件 (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 等)。同样由于某种原因,在读取文件时,我的代码忽略了类值(如 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'],.......}

【问题讨论】:

  • 为什么不把items 列表改成合适的字典呢?
  • 你想要一个嵌套字典?

标签: python python-3.x file dictionary yolo


【解决方案1】:

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

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

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

然后,要仅处理您的“.txt”文件,您可以使用globbing。 使用python的pathlib,使用Path().glob()会返回Path对象,有两个好处:

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

最后,您可以使用csv's DictReader 类直接返回具有您想要的形式的字典。只需指定字段名(这将是您的 dict 的键)和一个 ' '(空格)作为分隔符,这样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')

【讨论】:

    【解决方案2】:

    假设您在文件夹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>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
            }
        ]
    }
    

    【讨论】:

      【解决方案3】:

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

          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))
      
          
      

      【讨论】:

        【解决方案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']}
         
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-12-23
          • 1970-01-01
          • 2011-03-14
          • 2017-11-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多