在 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_dict
,collections.<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')
我有一个文本文件 (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_dict
,collections.<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')