Home > Net >  Shuffle content in a YAML file
Shuffle content in a YAML file

Time:04-24

I have this YAML file and I have a list with the strings I want to shuffle:

List: ['StmRsBgmSea02', 'StmRsBgmShopRadio', 'StmRsBgmSea01', ...] This is not the complete list.

YAML file:

Version: 3
IsBigEndian: False
SupportPaths: False
HasReferenceNodes: False
root:
  StageInfoList:
    - Name: SeaWorldHomeStage
      StageScenarioInfoList:
        - ScenarioNo: !l 0
          StagePlayInfoList:
            - {Name: WorldMain, ResourceName: StmRsBgmSea02}
            - {Name: Shop, ResourceName: StmRsBgmShopRadio}
        - ScenarioNo: !l 1
          StagePlayInfoList:
            - {Name: WorldMain, ResourceName: StmRsBgmSea01}
            - {Name: Boss, ResourceName: StmRsBgmBossHaikai_B}
            - {Name: Town, ResourceName: StmRsBgmSea01beach}
            - {Name: BossDead, ResourceName: WsdRsBgmJgSeaFountain}
    - Name: SeaWorldCostumeStage
      StageScenarioInfoList:
        - ScenarioNo: !l 0
          StagePlayInfoList:
            - {Name: CostumeRoom, ResourceName: WsdRsBgmMarioPlayHula}

The file is 800 lines long. I have a list with every name that comes after ResourceName:

I want that every value after ResourceName: will be replaced with one random value from the list. It is important that the string will be deleted from the list after one RessourceName will be randomized. So that no value occurs twice.

CodePudding user response:

When you load data from YAML (or JSON) you get an easy to recurse in data structure: everything is either a dict, a list or a value. You should make a routine that takes along the list of substitute values (here [v0, v1, v2, ...] while recursing and assign them whenever you find a key named ResourceName.

import sys
from pathlib import Path
import random
import ruamel.yaml


def recur(d, sub, key):
    if isinstance(d, dict):
        for k, v in d.items():
            if k == key:
                d[key] = selected = random.choice(sub)
                sub.remove(selected)
                continue
            recur(v, sub, key)
    elif isinstance(d, list):
        for elem in d:
            recur(elem, sub, key)
        

substitutes =['v0', 'v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9']
    
yaml = ruamel.yaml.YAML()
yaml.indent(mapping=2, sequence=4, offset=2)
data = yaml.load(Path('input.yaml'))
recur(data, substitutes, 'ResourceName')
yaml.dump(data, sys.stdout)

which gives:

Version: 3
IsBigEndian: false
SupportPaths: false
HasReferenceNodes: false
root:
  StageInfoList:
    - Name: SeaWorldHomeStage
      StageScenarioInfoList:
        - ScenarioNo: !l 0
          StagePlayInfoList:
            - {Name: WorldMain, ResourceName: v1}
            - {Name: Shop, ResourceName: v5}
        - ScenarioNo: !l 1
          StagePlayInfoList:
            - {Name: WorldMain, ResourceName: v2}
            - {Name: Boss, ResourceName: v0}
            - {Name: Town, ResourceName: v4}
            - {Name: BossDead, ResourceName: v3}
    - Name: SeaWorldCostumeStage
      StageScenarioInfoList:
        - ScenarioNo: !l 0
          StagePlayInfoList:
            - {Name: CostumeRoom, ResourceName: v7}

If appropriate, you might want to check if substitutes is empty after calling recur()

  • Related