代码之家  ›  专栏  ›  技术社区  ›  ShortCircuit

如何使用python从字典中编写yaml文件?

  •  5
  • ShortCircuit  · 技术社区  · 8 年前

    我有一个csv文件,其中包含数据,其中标题包含键,单元格包含值。我想使用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\u all()。

    1 回复  |  直到 8 年前
        1
  •  2
  •   Anthon    8 年前

    首先,你应该使用 dump() dump_all() ,因为您想编写YAML,而不是使用 load() .

    您还应该知道,CSV读取器在Python 2.7上返回的内容与在Python 3.6上返回的有所不同:首先 list 属于 dict 从返回 csv_dict_list 在第二个a 列表 属于 OrderedDict ). 这本身不会是一个问题,但Pyaml转储了一个带有已排序键的dict,以及一个带有标记的orderedict。

    您建议的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上