如何使用 python 从字典编写 yaml 文件?
How do I write a yaml file from a dictionary with python?
我有一个 csv 文件,其中包含数据,其中 header 包含键,单元格包含值。我想使用 python 从 csv 文件的内容创建一个 yaml 文件。
我创建了 K:V 对的字典;但是,我一直在尝试将 K:V 对放入 yaml 文件中。
yaml 的结构必须是:
key1: value1
key2: value2
key3:
- key4: value4
key5: {key6: [value6]
key7: value7
key8: value8
key9: value9
-
-
---
如果我手动创建这些,我将有超过 1000 个 YAML,因此这非常耗时且不切实际。
我正在寻找您更有经验的人可能有的任何想法。
我真的希望输出遍历字典以创建如下所示的大量 YAML 列表:
key1: value1
key2: value2
key3:
- key4: value4
key5: {key6: [value6]
key7: value7
key8: value8
key9: value9
-
-
---
key1: value1
key2: value2
key3:
- key4: value4
key5: {key6: [value6]
key7: value7
key8: value8
key9: value9
-
-
---
key1: value1
key2: value2
key3:
- key4: value4
key5: {key6: [value6]
key7: value7
key8: value8
key9: value9
-
-
---
key1: value1
key2: value2
key3:
- key4: value4
key5: {key6: [value6]
key7: value7
key8: value8
key9: value9
-
-
---
示例代码:
import csv
import yaml
def csv_dict_list(variables_file) :
reader=csv.DictReader(open(variables_file, 'r'))
dict_list = []
for line in reader:
dict_list.append(line)
return dict_list
yaml_values = csv_dict_list(sys.argv[1])
无论我在此之后尝试什么,我都无法使用 yaml.load() 或 yaml.load_all() 获得所需的输出。
首先,你应该使用dump()
或dump_all()
,因为你想写YAML,而不是使用load()
。
您还应该知道 CSV reader 在 Python 2.7 上做了 return 不同的事情,例如在 Python 3.6 上:第一次你从 csv_dict_list
得到 list
的 dict
,第二次得到 OrderedDict
的 list
。这本身不是问题,但 PyYAML 会转储一个带有排序键的字典,以及一个带有标签的有序字典。
您提议的 YAML 也无效,因为行中的流样式映射:
key5: {key6: [value6]
在文件结束前没有以}
结束,你也不能有:
key9: value9
-
-
要么使用:
key9: value9
key10:
-
-
或
key9:
- value9
-
或类似的东西(也没有等效的 Python 数据结构同时具有一个值和一个相同键的列表,因此即使在 Python 中也不能创建类似的东西).
PyYAML 还不支持缩进块样式序列。如果你这样做:
import yaml
print(yaml.dump(dict(x=[dict(a=1, b=2)]), indent=4))
输出仍将向左齐平:
x:
- {a: 1, b: 2}
为了防止你在使用 PyYAML 时 运行 遇到所有这些问题,并且为了避免 Python 版本之间的差异,我建议你使用 ruamel.yaml (免责声明:我是该软件包的作者)和以下代码:
import sys
import csv
import ruamel.yaml
Dict = ruamel.yaml.comments.CommentedMap
def csv_dict_list(variables_file) :
reader=csv.reader(open(variables_file, 'r'))
key_list = None
dict_list = []
for line in reader:
if key_list is None:
key_list = line
continue
d = Dict()
for idx, v in enumerate(line):
k = key_list[idx]
# special handling of key3/key4/key5/key6
if k == key_list[2]:
d[k] = []
elif k == key_list[3]:
d[key_list[2]].append(Dict([(k, v)]))
elif k == key_list[4]:
d[key_list[2]][0][k] = dt = Dict()
dt.fa.set_flow_style()
elif k == key_list[5]:
d[key_list[2]][0][key_list[4]][k] = [v]
else:
d[k] = v
dict_list.append(d)
return dict_list
data = csv_dict_list('test.csv')
yaml = ruamel.yaml.YAML()
yaml.indent(sequence=4, offset=2)
yaml.dump_all(data, sys.stdout)
与test.csv
:
key1,key2,key3,key4,key5,key6,key7,key8,key9
value_a1,value_a2,value_a3,value_a4,value_a5,value_a6,value_a7,value_a8,value_a9
value_b1,value_b2,value_b3,value_b4,value_b5,value_b6,value_b7,value_b8,value_b9
这给出:
key1: value_a1
key2: value_a2
key3:
- key4: value_a4
key5: {key6: [value_a6]}
key7: value_a7
key8: value_a8
key9: value_a9
---
key1: value_b1
key2: value_b2
key3:
- key4: value_b4
key5: {key6: [value_b6]}
key7: value_b7
key8: value_b8
key9: value_b9
Python 2.7 和 Python 3.6
我有一个 csv 文件,其中包含数据,其中 header 包含键,单元格包含值。我想使用 python 从 csv 文件的内容创建一个 yaml 文件。
我创建了 K:V 对的字典;但是,我一直在尝试将 K:V 对放入 yaml 文件中。
yaml 的结构必须是:
key1: value1
key2: value2
key3:
- key4: value4
key5: {key6: [value6]
key7: value7
key8: value8
key9: value9
-
-
---
如果我手动创建这些,我将有超过 1000 个 YAML,因此这非常耗时且不切实际。
我正在寻找您更有经验的人可能有的任何想法。
我真的希望输出遍历字典以创建如下所示的大量 YAML 列表:
key1: value1
key2: value2
key3:
- key4: value4
key5: {key6: [value6]
key7: value7
key8: value8
key9: value9
-
-
---
key1: value1
key2: value2
key3:
- key4: value4
key5: {key6: [value6]
key7: value7
key8: value8
key9: value9
-
-
---
key1: value1
key2: value2
key3:
- key4: value4
key5: {key6: [value6]
key7: value7
key8: value8
key9: value9
-
-
---
key1: value1
key2: value2
key3:
- key4: value4
key5: {key6: [value6]
key7: value7
key8: value8
key9: value9
-
-
---
示例代码:
import csv
import yaml
def csv_dict_list(variables_file) :
reader=csv.DictReader(open(variables_file, 'r'))
dict_list = []
for line in reader:
dict_list.append(line)
return dict_list
yaml_values = csv_dict_list(sys.argv[1])
无论我在此之后尝试什么,我都无法使用 yaml.load() 或 yaml.load_all() 获得所需的输出。
首先,你应该使用dump()
或dump_all()
,因为你想写YAML,而不是使用load()
。
您还应该知道 CSV reader 在 Python 2.7 上做了 return 不同的事情,例如在 Python 3.6 上:第一次你从 csv_dict_list
得到 list
的 dict
,第二次得到 OrderedDict
的 list
。这本身不是问题,但 PyYAML 会转储一个带有排序键的字典,以及一个带有标签的有序字典。
您提议的 YAML 也无效,因为行中的流样式映射:
key5: {key6: [value6]
在文件结束前没有以}
结束,你也不能有:
key9: value9
-
-
要么使用:
key9: value9
key10:
-
-
或
key9:
- value9
-
或类似的东西(也没有等效的 Python 数据结构同时具有一个值和一个相同键的列表,因此即使在 Python 中也不能创建类似的东西).
PyYAML 还不支持缩进块样式序列。如果你这样做:
import yaml
print(yaml.dump(dict(x=[dict(a=1, b=2)]), indent=4))
输出仍将向左齐平:
x:
- {a: 1, b: 2}
为了防止你在使用 PyYAML 时 运行 遇到所有这些问题,并且为了避免 Python 版本之间的差异,我建议你使用 ruamel.yaml (免责声明:我是该软件包的作者)和以下代码:
import sys
import csv
import ruamel.yaml
Dict = ruamel.yaml.comments.CommentedMap
def csv_dict_list(variables_file) :
reader=csv.reader(open(variables_file, 'r'))
key_list = None
dict_list = []
for line in reader:
if key_list is None:
key_list = line
continue
d = Dict()
for idx, v in enumerate(line):
k = key_list[idx]
# special handling of key3/key4/key5/key6
if k == key_list[2]:
d[k] = []
elif k == key_list[3]:
d[key_list[2]].append(Dict([(k, v)]))
elif k == key_list[4]:
d[key_list[2]][0][k] = dt = Dict()
dt.fa.set_flow_style()
elif k == key_list[5]:
d[key_list[2]][0][key_list[4]][k] = [v]
else:
d[k] = v
dict_list.append(d)
return dict_list
data = csv_dict_list('test.csv')
yaml = ruamel.yaml.YAML()
yaml.indent(sequence=4, offset=2)
yaml.dump_all(data, sys.stdout)
与test.csv
:
key1,key2,key3,key4,key5,key6,key7,key8,key9
value_a1,value_a2,value_a3,value_a4,value_a5,value_a6,value_a7,value_a8,value_a9
value_b1,value_b2,value_b3,value_b4,value_b5,value_b6,value_b7,value_b8,value_b9
这给出:
key1: value_a1
key2: value_a2
key3:
- key4: value_a4
key5: {key6: [value_a6]}
key7: value_a7
key8: value_a8
key9: value_a9
---
key1: value_b1
key2: value_b2
key3:
- key4: value_b4
key5: {key6: [value_b6]}
key7: value_b7
key8: value_b8
key9: value_b9
Python 2.7 和 Python 3.6