YAML:不带引号转储Python列表

9

我有一个Python列表my_list,它看起来像这样:["test1", "test2", "test3"]。我只想将它转储到一个YAML文件中,而不带引号。所以期望的输出是:

test_1
test_2
test_3

我已经尝试过:

import yaml
with open("my_yaml.yaml", "w") as f:
    yaml.safe_dump(my_list, f)

不幸的是,这包括在同一行上的所有3个元素,并且它们都被引用:

'test_1'、'test_2'、'test_3'

我该如何修改以获得期望的输出?

2个回答

8

尝试使用default_style=None来避免引号,以及default_flow_style=False将项单独输出到不同的行:

yaml.safe_dump(my_list, f, default_style=None, default_flow_style=False)

谢谢。所以现在每行只有一个,但是每行开头有一个破折号,并且仍然带引号 :( - anon_swe
您的实际数据可能包含特殊字符,如果是这样,无论如何都会被引用。对于您的示例数据test_1等,它不会被引用。每行开头的破折号只是YAML格式化列表数据的方式。 - blhsing

1
您想将Python列表作为多行纯量输出,这可能有些困难。通常情况下,列表会输出为YAML序列,其中使用破折号(-)或方括号([])来表示,前者是块样式,跨越多行,后者是流样式,在一行或多行上使用。
块样式示例:
import sys
from ruamel.yaml import YAML

data = ["test1", "test2", "test3"]

yaml = YAML()
yaml.dump(data, sys.stdout)

给出:
- test1
- test2
- test3

流动样式,在一条窄线上:

yaml = YAML()
yaml.default_flow_style = True
yaml.dump(data, sys.stdout)

输出:

流程样式,变窄:

[test1, test2, test3]
yaml = YAML()
yaml.default_flow_style = True
yaml.width = 5
yaml.dump(data, sys.stdout)

gets you:

[test1,
test2,
test3]

这不太可能是您想要的,因为它会影响整个YAML文档,并且仍然保留方括号。
另一种选择是将字符串转换为普通标量。实际上,这就是您想要的输出加载的方式。
yaml_str = """\
test_1
test_2
test_3
"""

yaml = YAML()
x = yaml.load(yaml_str)
assert type(x) == str
assert x == 'test_1 test_2 test_3'

加载您期望的输出通常是测试您需要提供什么的好方法。

因此,您必须将列表转换为多个单词字符串。再次出现的问题是,我所知道的任何YAML库都只能通过设置文档的宽度来强制换行,并且大多数情况下最小宽度都大于4(尽管可以进行修补,但这并不能解决整个文档都适用于此的问题)。

yaml = YAML()
yaml.width = 5
s = ' '.join(data)
yaml.dump(s, sys.stdout)

result:

test1 test2
test3
...

这里有一个在我看来是最好的解决方案,如果你真的不想使用破折号:使用一个字面块样式标量(字符串):literal block style scalar
from ruamel.yaml.scalarstring import PreservedScalarString

yaml = YAML()
s = PreservedScalarString('\n'.join(data) + '\n')
yaml.dump(s, sys.stdout)

在标量样式中,换行符会被保留:

|
test1
test2
test3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接