yaml-fi中的因子映射键

2024-09-28 23:15:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个YAML文件:

pb:
  {EF:{16, 19}, EH:{16, 19}}

当我应用我的flattendictPython函数时,我得到

^{pr2}$

我搜索我的YAML文件的语法如下,以获得相同的结果(我想要分解我的YAML节点数据)

pb:
  {EF, EH}, {16, 19}}

你有主意吗?在

这里是python flattendict函数

#!/usr/bin/env python
#encoding: UTF-8
import codecs
import sys
import yaml
import pprint

import collections

from collections import Mapping
from itertools import chain
from operator import add

_FLAG_FIRST = object()

def flattenDict(d, join=add, lift=lambda x:x):
    results = []
    def visit(subdict, results, partialKey):
        for k,v in subdict.items():
            newKey = lift(k) if partialKey==_FLAG_FIRST else join(partialKey,lift(k))
            if isinstance(v,Mapping):
                visit(v, results, newKey)
            else:
                results.append((newKey,v))
    visit(d, results, _FLAG_FIRST)
    return results

testdata = yaml.safe_load(open('data.yaml', 'r')) 
from pprint import pprint as pp
result = flattenDict(testdata, lift=lambda x:(x,))
pp(dict(result))

Tags: 文件fromimportyamlvisitresultsfirstflag
1条回答
网友
1楼 · 发布于 2024-09-28 23:15:55

在YAML中,你可以有一个复杂的流节点,甚至在一个简单的键中(即没有?,标记)。在YAML 1.2和{a2}中都是如此。这意味着:

{a: 1, b: 2}: mapping
[1, 2, a]: sequence

是正确的。在

问题是映射通常作为Python dict加载,而序列作为Python list加载,这两个都是可变的,不能散列,并且不允许作为Python dict的键(尝试执行python -c "{{'a': 1}: 2}")。在

PyYAML(支持yaml1.1)在这两行上都出现错误。在

由于Python有一个不可变的list,所以我决定在Python中实现序列键的加载,方法是将它们构造为ruamel.yaml(它支持yaml1.2和yaml1.1)中的元组。因此,以下工作是可行的:

^{pr2}$

打印:

{('pb', 'EF', 16): None,
 ('pb', 'EF', 19): None,
 ('pb', 'EH', 16): None,
 ('pb', 'EH', 19): None}
    -
[pb, EF, 16]:
[pb, EF, 19]:
[pb, EH, 16]:
[pb, EH, 19]:

如果尝试在PyYAML中加载上述YAML,则会引发异常:

found unhashable key
  in "<unicode string>", line 1, column 1:
    [pb, EF, 16]: 

注意事项:

  • 如果您不想往返,请使用typ="safe",它使用更快的C-loader,它也处理序列的键,但是它没有那么聪明地将那些键转储回去,结果是?标记了显式键。

  • {{cd3}不支持cd3}的标准映射。如果您有这样一个冻结dict,当然可以将其添加到ruamel.yaml的构造函数中。

  • 虽然Python中有一个^{},在YAML中有一个集合,ruamel.yaml当前不接受以下输入:

    !!set {a , b}: value
    
  • 可能不用说:如果不删除并重新添加键值对,就无法以编程方式更改此类键的元素。

相关问题 更多 >