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

已查看 1,392 次
跳至第一个未读帖子

Mike Titus

未读,
2016年12月2日 14:03:382016/12/2
收件人 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

未读,
2016年12月2日 14:40:382016/12/2
收件人 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

未读,
2016年12月2日 18:52:092016/12/2
收件人 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.
回复全部
回复作者
转发
0 个新帖子