#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
notA1
, поэтому вам следует начать с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. Спасибо, что сделали это за меня. также принял во внимание другие ваши советы.