[英]YAML list -> Python generator?
我想知道是否有一種簡單的方法可以使用PyYAML將包含項目列表的YAML文檔解析為python生成器。
例如,給定文件
# foobar.yaml
---
- foo: ["bar", "baz", "bah"]
something_else: blah
- bar: yet_another_thing
我希望能夠做類似的事情
for item in yaml.load_as_generator(open('foobar.yaml')): # does not exist
print(str(item))
我知道有yaml.load_all,它可以實現類似的功能,但隨后您需要將每個記錄視為其自己的文檔。 我問的原因是因為我有一些很大的文件要轉換為YAML,然后以低內存占用進行解析。
我看了看PyYAML Events API,但嚇到我了=)
我可以理解,Events API會讓您感到恐懼,而且只會帶給您如此之多。 首先,您需要跟蹤深度(因為您擁有頂層的復雜序列項以及“ bar”,“ baz”等。而且,正確剪切了低層序列事件元素后,您將不得不添加將它們放入作曲家以創建節點(以及最終的Python對象),這也不是一件容易的事。
但是由於YAML使用縮進,即使對於跨越多行的標量,您也可以使用基於行的簡單解析器來識別每個序列元素的起始位置,並將其一次輸入到常規的load()
函數中:
#/usr/bin/env python
import ruamel.yaml
def list_elements(fp, depth=0):
buffer = None
in_header = True
list_element_match = ' ' * depth + '- '
for line in fp:
if line.startswith('---'):
in_header = False
continue
if in_header:
continue
if line.startswith(list_element_match):
if buffer is None:
buffer = line
continue
yield ruamel.yaml.load(buffer)[0]
buffer = line
continue
buffer += line
if buffer:
yield ruamel.yaml.load(buffer)[0]
with open("foobar.yaml") as fp:
for element in list_elements(fp):
print(str(element))
導致:
{'something_else': 'blah', 'foo': ['bar', 'baz', 'bah']}
{'bar': 'yet_another_thing'}
我在這里使用了PyYAML的增強版本ruamel.yaml (我是作者),但是PyYAML應該以相同的方式工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.