How to "flatten" nested keys in a dictionary, when key structure varies?

1.394 visualizações
Pular para a primeira mensagem não lida

Mike Titus

não lida,
2 de dez. de 2016, 14:03:3802/12/2016
para Ansible Project
Given this YAML:

somevar:
  alpha:
    beta:
      gamma:
        foo1: bar1
        foo2: bar2
  red:
    green:
      blue:
        baz1: quz1
        baz2: quz2

I want to construct strings of the full key paths:

somevar/alpha/beta/gamma
somevar/red/green/blue

Thanks.

Matt Martz

não lida,
2 de dez. de 2016, 14:40:3802/12/2016
para ansible...@googlegroups.com
There is no built in way to do this, however with a new custom filter, maybe you can get it:

def dict_path(my_dict, path=None):
    if path is None:
        path = []
    for k, v in my_dict.iteritems():
        newpath = path + [k]
        if isinstance(v, dict):
            for u in dict_path(v, newpath):
                yield u
        else:
            yield newpath, v

class FilterModule(object):
    def filters(self):
        return {
            'dict_path': dict_path
        }

And then a playbook that makes use of this:

---
- hosts: all
  vars:
    somevar:
      alpha:
        beta:
          gamma:
            foo1: bar1
            foo2: bar2
      red:
        green:
          blue:
            baz1: quz1
            baz2: quz2
  tasks:
    - debug:
        msg: "{{ item.0|join('/') }} => {{ item.1 }}"
      with_items:
        - "{{ somevar|dict_path|list }}"

Results in the output of (restricted to 1 item from the loop for brevity):

ok: [localhost] => (item=([u'alpha', u'beta', u'gamma', u'foo1'], u'bar1')) => {
    "item": [
        [
            "alpha",
            "beta",
            "gamma",
            "foo1"
        ],
        "bar1"
    ],
    "msg": "alpha/beta/gamma/foo1 => bar1"
}

with that, you could derive a playbook that makes those paths, puts the values into files, etc...


--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-project+unsubscribe@googlegroups.com.
To post to this group, send email to ansible-project@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/789e9f46-0246-4f33-abd0-f7ca961b6363%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Matt Martz
@sivel
sivel.net

Mike Titus

não lida,
2 de dez. de 2016, 18:52:0902/12/2016
para Ansible Project
That worked perfectly -- thanks so much!
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
Responder a todos
Responder ao autor
Encaminhar
0 nova mensagem