Python выполняет итерацию через YAML

#python #yaml #pyyaml

#python #yaml #pyyaml

Вопрос:

Как можно выполнить итерацию через:

 A:
  A1: 1000
  A2:
    A2A:
      A2A1: 100
      A2A2: 250
      A2A3: 250
    A2B:
      A2B1: 100
      A2B2: 300
   A3:
     A3A:
       A3A1:
         A3A1A: 200
         A3A1B: 100
         # There could be more values
  

Я хочу добавить значения A3A1A и A3A1B и другие значения в том же месте

Я попробовал следующее:

     with open("foobar.yml", 'r') as stream:
            foobar = yaml.load(stream)
    end_value = 0
        for one_value in foobar["A1"]["A3"]["A3A"] ["A3A1"][*]:
           end_value = end_value   one_value 
  

но это не работает

Ответ №1:

Здесь есть несколько проблем:

  • Ваш YAML недействителен. Ключ A3 не совпадает с A2 (или A2B ). Я предполагаю, что вы хотите, чтобы это было согласовано с A2
  • ключом в сопоставлении корневого уровня является A not A1 , поэтому вам следует начать с foobar['A'] обхода структуры данных.
  • не существует такой вещи, как [*] use .items() для получения пар ключ-значение или .values() для получения только значений вложенного отображения / dict
  • у вашего for оператора неверный отступ
  • вы используете PyYAML load() , который задокументирован как потенциально небезопасный, и нет необходимости его использовать. Используйте safe_load() или обновитесь до ruamel.yaml , что дает вам YAML 1.2 и многое другое (отказ от ответственности: я являюсь автором ruamel.yaml)

Например, вы можете сделать:

 import sys
import ruamel.yaml


yaml = ruamel.yaml.YAML(typ='safe')
with open('foobar.yaml') as fp:
  data = yaml.load(fp)

end_value = 0
for one_value in  data['A']['A3']['A3A']['A3A1'].values():
   end_value  = one_value

print(end_value)
  

что дает:

 300
  

Комментарии:

1. Спасибо, что сделали это за меня. также принял во внимание другие ваши советы.