Reputation: 6831
In my yam file I am trying this
with open(fname, "w") as f:
yaml.safe_dump({'items':['test', 'test2']}, f,
default_flow_style=False, width=50, indent=4)
It prints in the below format
items:
- 'test'
- 'test2'
I want the output formatted like below
items: ['test', 'test2']
How can I do that ?
EDIT:
This is my complete code
d = {}
for m in ['B1', 'B2', 'B3']:
d2 = {}
for f in ['A1', 'A2', 'A3']:
# here i don't want any flow style
d2[f] = ['test', 'test2']
d[m] = d2
with open(fname, "w") as f:
yaml.safe_dump(d, f, default_flow_style=True, width=50, indent=8)
Upvotes: 2
Views: 3858
Reputation: 76792
If you want fine control and only have specific lists with flow style, you should use ruamel.yaml (which is my enhanced version of PyYAML):
import ruamel.yaml
from ruamel.yaml.comments import CommentedSeq
d = {}
for m in ['B1', 'B2', 'B3']:
d2 = {}
for f in ['A1', 'A2', 'A3']:
# here i don't want any flow style
d2[f] = CommentedSeq(['test', 'test2'])
if f != 'A2':
d2[f].fa.set_flow_style()
d[m] = d2
x = ruamel.yaml.dump(
d, Dumper=ruamel.yaml.RoundTripDumper,
default_flow_style=False, width=50, indent=8)
print(x)
will give you:
B1:
A1: [test, test2]
A3: [test, test2]
A2:
- test
- test2
B2:
A1: [test, test2]
A3: [test, test2]
A2:
- test
- test2
B3:
A1: [test, test2]
A3: [test, test2]
A2:
- test
- test2
The CommentedSeq
behaves just like a normal Python list, but allows you to specify comment, set flow/block style etc.
ruamel.yaml
is normally used to preserve comments, flow/block style on elements, etc., when round-tripping YAML. I.e. if you would append:
d2 = ruamel.yaml.load(x, Loader=ruamel.yaml.RoundTripLoader)
y = ruamel.yaml.dump(
d2, Dumper=ruamel.yaml.RoundTripDumper, width=50, indent=8)
assert x == y
the assertion holds.
But it can of course be used to genenerate YAML from scratch as well. You could e.g. also use the CommentedMap type and keep the keys of your dict/mapping ordered.
Upvotes: 2
Reputation: 14126
Don't put the default_flow_style=False
then, does the complete opposite of what you want:
>>> import yaml
>>> yaml.safe_dump({'items': ['test', 'test2']}, default_flow_style=False)
'items:\n- test\n- test2\n'
>>> yaml.safe_dump({'items': ['test', 'test2']})
'items: [test, test2]\n'
As for partial document formatting, you can do with custom representers, e.g.:
class Items(list):
pass
def items_representer(dumper, data):
return dumper.represent_sequence('tag:yaml.org,2002:seq', data, flow_style=True)
yaml.representer.SafeRepresenter.add_representer(Items, items_representer)
result = yaml.safe_dump({
'items': Items(['test', 'test2']),
'other list': ['1', '2'],
}, default_flow_style=False)
# items: [test, test2]
# other list:
# - '1'
# - '2'
print(result)
Upvotes: 2