Search code examples
yamlpyyamlruamel.yaml

Numeric keys in YAML files


Is there any way to stringify numeric keys in a YAML file? I have a sample input file as so:

foo: bar
123: New York
food: Cheese
23.61 : max_value

I'm using the ruamel package to process my files - is there anything available in the loading or dumping calls that could perform the conversion so it would look like:

foo: bar
'123': New York
food: Cheese
'23.61' : max_value

or even all the keys ...

'foo': bar
'123': New York
'food': Cheese
'23.61': max_value

I looked through the API but couldn't see anything obvious ...


Solution

  • There is no loading option that makes all keys strings, but you can do that after loading with a small recursive function:

    import sys
    import ruamel.yaml
    
    yaml_str = """\
    foo: bar
    123: New York
    food: Cheese
    23.61 : max_value
    """
    
    def keys2string(d):
        if isinstance(d, dict):
            for idx, k in enumerate(list(d.keys())):
                if not isinstance(k, str):
                    sk = str(k)
                    d.insert(idx, str(k), d.pop(k))
                    k = sk
                keys2string(d[k])
        elif isinstance(d, list):
            for e in d:
                keys2string(e)
    
    
    yaml = ruamel.yaml.YAML()
    yaml.preserve_quotes = True
    data = yaml.load(yaml_str)
    keys2string(data)
    yaml.dump(data, sys.stdout)
    

    which gives:

    foo: bar
    '123': New York
    food: Cheese
    '23.61': max_value
    

    The use of .insert() is one possible way of preserving the order of the keys (i.e. have the stringified keys be in the place of their original numeric keys).