按特定顺序从 .txt 中读取项目
Reading items from .txt in specific order
我正在尝试从包含以下内容的 .txt 文件中读取项目:
294.nii.gz [[9, 46, 54], [36, 48, 44], [24, 19, 46], [15, 0, 22]]
296.nii.gz [[10, 13, 62], [40, 1, 64], [34, 0, 49], [27, 0, 49]]
312.nii.gz [[0, 27, 57], [25, 25, 63], [0, 42, 38], [0, 11, 21]]
我想提取数据的方式是:
- 获取物品名称:
294.nii.gz
- 项目坐标连续:
[9, 46, 54]
[36, 48, 44]
...
- 获取下一项:
N.B。所有项目都具有相同数量的 3D 坐标。
到目前为止,我可以通过以下代码读取数据:
coortxt = os.path.join(coordir, 'coor_downsampled.txt')
with open(coortxt) as f:
content = f.readlines()
content = [x.strip() for x in content]
for item in content:
print(item.split(' ')[0])
这只打印项目名称:
294.nii.gz
296.nii.gz
312.nii.gz
如何以我需要的格式获取其余数据?
因此,您完成了将列表的字符串表示形式转换为列表的有趣任务。
为此,您可以使用 ast library. Specifically, the ast.literal_eval
方法。
免责声明:
根据文档:
Warning It is possible to crash the Python interpreter with a sufficiently large/complex string due to stack depth limitations in Python’s AST compiler.
这与使用 eval
不同。来自 docs:
Safely evaluate an expression node or a string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.
This can be used for safely evaluating strings containing Python expressions from untrusted sources without the need to parse the values oneself.
你得到数据的第一部分item.split(' ')[0]
。
然后,您将使用 item.split(' ')[1:]
获取(例如)内容为 "[[9, 46, 54], [36, 48, 44], [24, 19, 46], [15, 0, 22]]"
.
的字符串
如果这是您愿意接受的风险:
使用ast
的演示:
import ast
list_str = "[[9, 46, 54], [36, 48, 44], [24, 19, 46], [15, 0, 22]]"
list_list = ast.literal_eval(list_str)
print(isinstance(list_list, list))
#Outputs True
print(list_list)
#Outputs [[9, 46, 54], [36, 48, 44], [24, 19, 46], [15, 0, 22]]
将它与您的代码结合在一起:
import os
import ast
coortxt = os.path.join(coordir, 'coor_downsampled.txt')
with open(coortxt) as f:
content = f.readlines()
content = [x.strip() for x in content]
for item in content:
name,coords_str = item.split(' ')[0], item.split(' ')[1:]
coords = ast.literal_eval(coords_str)
#name,coords now contain your required data
#use as needed
相关帖子:
How to convert string representation of list to a list?
其他人建议在 Python 中使用动态求值器 eval
(甚至 ast.literal_eval
,这确实有效,但仍然有一些方法可以在没有它的情况下执行这种解析.
鉴于 coor_downsampled.txt
文件中坐标列表的格式非常 json-esque,我们可以使用非常酷的 json
模块来解析它。
注意:
有消息称 json.loads is 4x faster than eval, and almost 7x faster than ast.literal_eval,这取决于您是否需要速度,我建议您使用更快的选项。
完整示例
import os
import json
coortxt = 'coor_downsampled.txt'
with open(coortxt) as f:
content = f.readlines()
content = [x.strip() for x in content]
for item in content:
# split the line just like you did in your own example
split_line = item.split(" ")
# the "name" is the first element
name = split_line[0]
# here's the tricky part.
coords = json.loads("".join(split_line[1:]))
print(name)
print(coords)
说明
让我们分解一下这条棘手的线coords = json.loads("".join(split_line[1:]))
split_line[1:]
会给你第一个 space 之后的所有内容,所以像这样:
['[[9,', '46,', '54],', '[36,', '48,', '44],', '[24,', '19,', '46],', '[15,', '0,', '22]]']
但是用"".join()
包裹它,我们可以把它变成
'[[9,46,54],[36,48,44],[24,19,46],[15,0,22]]'
改为字符串。
一旦我们有了它,我们只需json.loads()
来获取实际的列表对象
[[9, 46, 54], [36, 48, 44], [24, 19, 46], [15, 0, 22]]
.
我正在尝试从包含以下内容的 .txt 文件中读取项目:
294.nii.gz [[9, 46, 54], [36, 48, 44], [24, 19, 46], [15, 0, 22]]
296.nii.gz [[10, 13, 62], [40, 1, 64], [34, 0, 49], [27, 0, 49]]
312.nii.gz [[0, 27, 57], [25, 25, 63], [0, 42, 38], [0, 11, 21]]
我想提取数据的方式是:
- 获取物品名称:
294.nii.gz
- 项目坐标连续:
[9, 46, 54]
[36, 48, 44]
... - 获取下一项:
N.B。所有项目都具有相同数量的 3D 坐标。
到目前为止,我可以通过以下代码读取数据:
coortxt = os.path.join(coordir, 'coor_downsampled.txt')
with open(coortxt) as f:
content = f.readlines()
content = [x.strip() for x in content]
for item in content:
print(item.split(' ')[0])
这只打印项目名称:
294.nii.gz
296.nii.gz
312.nii.gz
如何以我需要的格式获取其余数据?
因此,您完成了将列表的字符串表示形式转换为列表的有趣任务。
为此,您可以使用 ast library. Specifically, the ast.literal_eval
方法。
免责声明:
根据文档:
Warning It is possible to crash the Python interpreter with a sufficiently large/complex string due to stack depth limitations in Python’s AST compiler.
这与使用 eval
不同。来自 docs:
Safely evaluate an expression node or a string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.
This can be used for safely evaluating strings containing Python expressions from untrusted sources without the need to parse the values oneself.
你得到数据的第一部分item.split(' ')[0]
。
然后,您将使用 item.split(' ')[1:]
获取(例如)内容为 "[[9, 46, 54], [36, 48, 44], [24, 19, 46], [15, 0, 22]]"
.
如果这是您愿意接受的风险:
使用ast
的演示:
import ast
list_str = "[[9, 46, 54], [36, 48, 44], [24, 19, 46], [15, 0, 22]]"
list_list = ast.literal_eval(list_str)
print(isinstance(list_list, list))
#Outputs True
print(list_list)
#Outputs [[9, 46, 54], [36, 48, 44], [24, 19, 46], [15, 0, 22]]
将它与您的代码结合在一起:
import os
import ast
coortxt = os.path.join(coordir, 'coor_downsampled.txt')
with open(coortxt) as f:
content = f.readlines()
content = [x.strip() for x in content]
for item in content:
name,coords_str = item.split(' ')[0], item.split(' ')[1:]
coords = ast.literal_eval(coords_str)
#name,coords now contain your required data
#use as needed
相关帖子:
How to convert string representation of list to a list?
其他人建议在 Python 中使用动态求值器 eval
(甚至 ast.literal_eval
,这确实有效,但仍然有一些方法可以在没有它的情况下执行这种解析.
鉴于 coor_downsampled.txt
文件中坐标列表的格式非常 json-esque,我们可以使用非常酷的 json
模块来解析它。
注意:
有消息称 json.loads is 4x faster than eval, and almost 7x faster than ast.literal_eval,这取决于您是否需要速度,我建议您使用更快的选项。
完整示例
import os
import json
coortxt = 'coor_downsampled.txt'
with open(coortxt) as f:
content = f.readlines()
content = [x.strip() for x in content]
for item in content:
# split the line just like you did in your own example
split_line = item.split(" ")
# the "name" is the first element
name = split_line[0]
# here's the tricky part.
coords = json.loads("".join(split_line[1:]))
print(name)
print(coords)
说明
让我们分解一下这条棘手的线coords = json.loads("".join(split_line[1:]))
split_line[1:]
会给你第一个 space 之后的所有内容,所以像这样:
['[[9,', '46,', '54],', '[36,', '48,', '44],', '[24,', '19,', '46],', '[15,', '0,', '22]]']
但是用"".join()
包裹它,我们可以把它变成
'[[9,46,54],[36,48,44],[24,19,46],[15,0,22]]'
改为字符串。
一旦我们有了它,我们只需json.loads()
来获取实际的列表对象
[[9, 46, 54], [36, 48, 44], [24, 19, 46], [15, 0, 22]]
.