3
votes

Lire et vider [bracket, list] depuis et vers yaml avec python

J'essaie de lire et de vider une liste sur yaml en utilisant le code suivant

chs_per_cath:
- - - 10
    - 11
    - 12
    - 13
  - - 13000
    - 13100
    - 13200
    - 13300
- - - 16
    - 17
    - 18
    - 19
    - 20
    - 21
    - 22
    - 23
    - 24
    - 25
  - - 13400
    - 13500
    - 13600
    - 13700
    - 13800
    - 13900
    - 14000
    - 14100
    - 14200
    - 14300
- - - 32
    - 33
    - 34
    - 35
    - 36
    - 37
    - 38
    - 39
    - 40
    - 41
  - - 13400
    - 13500
    - 13600
    - 13700
    - 13800
    - 13900
    - 14000
    - 14100
    - 14200
    - 14300

La liste d'entrée, comme dans le fichier:

chs_per_cath: [[[10, 11, 12, 13], [13000, 13100, 13200, 13300]],
 [[16, 17, 18, 19, 20, 21, 22, 23, 24, 25], [13400, 13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]],
 [[32, 33, 34, 35, 36, 37, 38, 39, 40, 41], [13400, 13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]]]


0 commentaires

3 Réponses :


1
votes

Veuillez jeter un œil à l'argument default_flow_style pour yaml.dump () .

Par défaut, PyYAML choisit le style d'une collection en fonction de s'il a des collections imbriquées. Si une collection est imbriquée collections, le style de bloc lui sera attribué. Sinon ça va avoir le style de flux.

Si vous souhaitez que les collections soient toujours sérialisées dans le style bloc, définissez le paramètre default_flow_style de dump () sur False.

https://pyyaml.org/wiki/PyYAMLDocumentation#DumpingYAML


0 commentaires

1
votes

Comme mentionné ici , utiliser default_flow_style devrait faire l'affaire.

Mais il semble que vous en avez réellement besoin réglé sur Vrai .

Ie

>>> d = {'chs_per_cath': [[[10, 11, 12, 13], [13000, 13100, 13200, 13300]],
  [[16, 17, 18, 19, 20, 21, 22, 23, 24, 25],
   [13400, 13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]],
  [[32, 33, 34, 35, 36, 37, 38, 39, 40, 41],
   [13400, 13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]]]}

>>> print(yaml.dump(d, default_flow_style=True))
{chs_per_cath: [[[10, 11, 12, 13], [13000, 13100, 13200, 13300]], [[16, 17, 18, 19,
        20, 21, 22, 23, 24, 25], [13400, 13500, 13600, 13700, 13800, 13900, 14000,
        14100, 14200, 14300]], [[32, 33, 34, 35, 36, 37, 38, 39, 40, 41], [13400,
        13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]]]}


2 commentaires

Cela a effectivement fait l'affaire pour la liste donnée, mais a détruit tout le reste du document. Par exemple, le system: testing: False d'origine est devenu {system: ...}


Eh bien, cela signifie que vous avez un formatage yaml incohérent dans le fichier source. Les deux sont des yaml valides. Pouvez-vous expliquer ce que vous essayez d'accomplir?



3
votes

Si vous voulez charger, puis vider (peut-être après avoir modifié certaines valeurs), PyYAML n'est pas le bon outil, car il va déformer beaucoup de choses dans la représentation syntaxique.

Cela supprimera le style de flux comme vous l'avez remarqué, mais aussi les commentaires, les noms d'ancre / alias, des formats d'entiers spécifiques (octal, hex, binaire), etc.

Il y a peu de contrôle sur le flux- vs style bloc de la sortie dans PyYAML. Vous pouvez avoir tout-bloc; collections de nœuds en tant que flux,
et vous pouvez avoir tout le flux, en utilisant le paramètre default_flow_style pour safe_dump () .

Vous feriez mieux d'utiliser ruamel.yaml (avertissement: je suis l'auteur de cette bibliothèque), car il prend en charge la norme YAML 1.2, maintenant vieille de 10 ans (où PyYAML ne gère que le YAML 1.1 obsolète) et vous obtiendrez une sortie beaucoup plus proche, et souvent identique à votre entrée YAML.

def FSlist(l):  # concert list into flow-style (default is block style)
    from ruamel.yaml.comments import CommentedSeq
    cs = CommentedSeq(l)
    cs.fa.set_flow_style()
    return cs

system_bsc_dict['existing_field'] = FSlist(["Boston Maestro 4000"])

Si vous êtes Python 3, vous pouvez utiliser:

from pathlib import Path
yaml_file = Path(system_bsc_path)
system_bsc_dict = yaml.load(yaml_file)
yaml.dump(system_bsc_dict, yaml_file)

Par défaut, toutes les nouvelles listes (et dictées) seront de style bloc, si vous voulez ajouter une liste de style flux, vous pouvez utilisez yaml.default_flow_style = True pour définir toutes ces listes, ou utilisez un contrôle fin en définissant l'attribut de flux ( .fa ) sur la représentation interne spéciale:

XXX


2 commentaires

Merci! J'utilise 2.7. Cela fonctionne mieux que yaml, avec une chose manquante: lors de l'ajout d'un champ system_bsc_dict ['existing_field'] = ["Boston Maestro 4000"] Il affiche en -dash style , plutôt que dans le [style de crochet] souhaité. Comment puis-je définir le style? Merci


J'ai mis à jour ma réponse. Pour Python 2.7, vous pouvez installer le package pathlib2 , ruamel.yaml fonctionnera également avec cela.