Ключ YAML, состоящий из списка элементов

Мне нужно иметь список элементов в качестве ключа, чтобы я мог проверить, выполняются ли несколько условий. Пример (не знаю, возможно ли это и правильный ли синтаксис):

mapping:
  c_id:
    [pak, gb]: '4711'
    [pak, ch]: '4712'
    [pak]: '4713'
  d_id:
    .
    .
    .

Теперь мне нужно знать, возможен ли подход, как в примере.


person GiftZwergrapper    schedule 15.09.2016    source источник


Ответы (2)


В дополнение к ответу Антона, вот как вы можете сделать это с PyYaml:

mapping:
  c_id:
    !!python/tuple [pak, gb]: '4711'
    !!python/tuple [pak, ch]: '4712'
    !!python/tuple [pak]: '4713'

Хитрость заключается в том, чтобы сообщить PyYaml, что вы хотите загрузить ключи в кортеж (поскольку список нельзя использовать в качестве ключа dict). Невозможно сделать это неявно, но это не значит, что это невозможно.

Явные ключи могут быть более читаемыми в этом случае:

mapping:
  c_id:
    ? !!python/tuple [pak, gb]
    : '4711'
    ? !!python/tuple [pak, ch]
    : '4712'
    ? !!python/tuple [pak]
    : '4713'

Этот пример семантически эквивалентен первому.

person flyx    schedule 15.09.2016
comment
Спас мою проблему, не переходя с PyYAML на любой другой модуль, спасибо! - person GiftZwergrapper; 15.09.2016

Синтаксис вашего YAML правильный. Единственный трюк заключается в том, что, поскольку в Python ключ должен быть неизменным, вам нужно указать доступ к сложному ключу в виде кортежа:

import ruamel.yaml

yaml_str = """\
mapping:
  c_id:
    [pak, gb]: '4711'
    [pak, ch]: '4712'
    [pak]: '4713'
"""

data = ruamel.yaml.round_trip_load(yaml_str)
print(data['mapping']['c_id'][('pak', 'gb')])

дает:

4711

Обратите внимание, что это невозможно с PyYAML, так как он не поддерживает последовательности в качестве ключей, вы должны использовать ruamel.yaml (отказ от ответственности: я являюсь автором этого пакета)

person Anthon    schedule 15.09.2016