将字典项的任意长度展平到Python的路径列表中

克杜根

因此,我在Python中以递归方式阅读了很多有关扁平化字典的文章。没有一个(保存一个)接近我想要的。首先,简要说明我要完成的工作:

具有混合条目的示例字典:(键和值始终是混合类型)

{'a': [{'b': {'c': 'd', 'e': 'f', 'g': 'h',
              'i': {'j': {'k': ['l'], 'm': 'n'}},
              'o': {'p': {'q': ['r', 's' ], 't': 'u'}}
              }
       }]
}

所需的输出:

{'a/b/c/d',
 'a/b/e/f',
 'a/b/g/h',
 'a/b/i/j/k/l',
 'a/b/i/j/m/n',
 'a/b/o/p/q/r',
 'a/b/o/p/q/s',
 'a/b/o/p/t/u'}

该函数也应该(理论上)在列表上工作。

为了解释一下我在做什么,我正在尝试通过Mac plist搜索,而其他尝试通过键或值进行搜索的尝试充其量只是摇摇欲坠。为了补偿,我想尝试另一种方法。将字典转换为“路径”列表,然后仅搜索路径。

我尝试了一下(并部分成功了),然后以这种形式找到了一个更好的解决方案:

def flatten(structure, key="", path="", flattened=None):
    if flattened is None:
        flattened = {}
    if type(structure) not in(dict, list):
        flattened[((path + "/") if path else "") + key] = structure
    elif isinstance(structure, list):
        for i, item in enumerate(structure):
            flatten(item, "", "/".join(filter(None,[path,key])), flattened)
    else:
        for new_key, value in structure.items():
            flatten(value, new_key, "/".join(filter(None,[path,key])), flattened)
    return flattened

这效果很好,但有一些不良影响。首先,输出如下:

{'a/b/c'     : 'd',
 'a/b/e'     : 'f',
 'a/b/g'     : 'h',
 'a/b/i/j/k/': 'l',
 'a/b/i/j/m' : 'n',
 'a/b/o/p/q/': 's',
 'a/b/o/p/t' : 'u'}

这将返回键/值对的字典。我宁愿有一个字符串路径列表。其次,更重要的是,您会注意到,脚本在值是列表的地方剥离了值。仅追加列表的最后一项。

'a/b/o/p/q/': 's' # there should be another entry with 'r' as the value.

我花了很多时间摆弄输出,并试图完全解决问题,但无济于事。这可能只是我对Python的了解,但是我想要的输出应该是可能的。

除非我没有其他选择,否则我会尽量不提出问题。请不要将其标记为重复项,因为其他问题并不能完全满足我的要求。

感谢您的时间和协助/指导。

不育

Python 2.7:

def flatten(structure):
    if isinstance(structure, basestring):
        return [structure]
    ret = []
    if isinstance(structure, list):
        for v in structure:
            ret.extend(flatten(v))
    elif isinstance(structure, dict):
        for k, v in structure.items():
            ret.extend(k + '/' + f for f in flatten(v))
    return ret

print sorted(flatten(structure))

输出:

['a/b/c/d', 'a/b/e/f', 'a/b/g/h', 'a/b/i/j/k/l', 'a/b/i/j/m/n', 'a/b/o/p/q/r', 'a/b/o/p/q/s', 'a/b/o/p/t/u']

或者,如果您不关心订单,可以简单地进行print flatten(structure)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章