在尝试使用本地yaml
库从python中的JSON创建YAML时,我能够将JSON转换为YAML。但是,在收到的YAML中,JSON的所有方括号都展开了,而我想保留从JSON到转换后的YAML的几个方括号(列表)。如何请求此库调用,以不将列表从JSON展开到YAML中,而是将其保留为列表?
以下是我的问题的快照:
import yaml
import json
original_json = {'a': {'next': ['b'], 'prev': []},
'b': {'next': ['c'], 'prev': ['a']},
'c': {'next': ['d', 'e'], 'prev': ['b']},
'd': {'next': [], 'prev': ['c']},
'e': {'next': ['f'], 'prev': ['c']},
'f': {'next': [], 'prev': ['e']}}
obtained_yaml = yaml.dump(yaml.load(json.dumps(original_json)), default_flow_style=False)
# obtained_yaml looks like
#
# a:
# next:
# - b
# prev: []
# b:
# next:
# - c
# prev:
# - a
# c:
# next:
# - d
# - e
# prev:
# - b
# d:
# next: []
# prev:
# - c
# e:
# next:
# - f
# prev:
# - c
# f:
# next: []
# prev:
# - e
# expected yaml should look like
#
# a:
# next:
# - ["b"]
# prev: []
# b:
# next:
# - ["c"]
# prev:
# - ["a"]
# c:
# next:
# - ["d"]
# - ["e"]
# prev:
# - ["b"]
# d:
# next: []
# prev:
# - ["c"]
# e:
# next:
# - ["f"]
# prev:
# - ["c"]
# f:
# next: []
# prev:
# - ["e"]
我尝试了几种方法来解决这个问题,但是所有这些都无法像预期的json那样工作。需要如何完成的建议。
答案 0 :(得分:1)
Yaml语法定义了一个不同的列表结构,其中列表的成员是在同一缩进级别以using BaseClass::x;
using BaseClass::y;
using BaseClass::z;
(破折号和空格)开头的行。如果您想保留方括号,则需要将列表强制转换为-
-但是您将失去将YAML反向转换为JSON的功能。
在此示例中,即使将str
放入["a"]
,您也可以看到-YAML将其转换为双缩进列表:
[["a"]]
答案 1 :(得分:0)
只有YAML 1.2是JSON的超集,但不是YAML 1.1,尽管YAML 1.2是在JSON中发布的 2009年,很遗憾,此后一直没有更新PyYAML。你的例子 是与YAML 1.1兼容的JSON子集,但总的来说这不是一个好主意 尝试为此使用PyYAML。
还有其他适用于Python的本机库,另一个是
ruamel.yaml
(免责声明:我是该软件包的作者),
实现YAML 1.2,并提供对块与流的完全控制
个人收藏的样式转储。当然你还有
常规YAML限制,即您不能使用块样式
流样式集合中的集合)。
PyYAML和ruamel.yaml在非往返模式下,仅允许您以流样式拥有所有块或所有流,或所有具有叶节点的块。但是默认的往返模式允许使用集合上的.fa
属性进行更精细的控制:
import sys
import json
import ruamel.yaml
original_json = {'a': {'next': ['b'], 'prev': []},
'b': {'next': ['c'], 'prev': ['a']},
'c': {'next': ['d', 'e'], 'prev': ['b']},
'd': {'next': [], 'prev': ['c']},
'e': {'next': ['f'], 'prev': ['c']},
'f': {'next': [], 'prev': ['e']}}
json_string = json.dumps(original_json)
yaml = ruamel.yaml.YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
# yaml.preserve_quotes = True
data = yaml.load(json_string)
# the following sets flow-style for the root level mapping only
data.fa.set_block_style()
yaml.dump(data, sys.stdout)
给出:
a: {next: [b], prev: []}
b: {next: [c], prev: [a]}
c: {next: [d, e], prev: [b]}
d: {next: [], prev: [c]}
e: {next: [f], prev: [c]}
f: {next: [], prev: [e]}
您当然可以递归地遍历数据结构,并根据所需的任何条件调用.fa.set_block_style()
。