首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python:将多个嵌套列表合并为一个字典

Python:将多个嵌套列表合并为一个字典
EN

Stack Overflow用户
提问于 2011-04-07 10:01:42
回答 3查看 2.9K关注 0票数 1

我有一堆类似下面两个的列表:

代码语言:javascript
运行
复制
['a', ['b', ['x', '1'], ['y', '2']]]
['a', ['c', ['xx', '4'], ['gg', ['m', '3']]]]

将它们组合成一个字典的最简单方法是什么:

代码语言:javascript
运行
复制
{'a': {
    'b': {
        'x':1,
        'y':2
    }
    'c': {
        'xx':4,
        'gg': {
            'm':3
        }
    }
}

嵌套的深度是可变的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-04-07 10:14:42

这是一个非常粗糙的实现,它不能处理奇怪的情况,比如列表中包含的元素少于两个,并且它覆盖了重复的键,但它可以帮助你入门:

代码语言:javascript
运行
复制
l1 = ['a', ['b', ['x', '1'], ['y', '2']]]
l2 = ['a', ['c', ['xx', '4'], ['gg', ['m', '3']]]]

def combine(d, l):
    if not l[0] in d:
        d[l[0]] = {}

    for v in l[1:]:
        if type(v) == list:
            combine(d[l[0]],v)
        else:
            d[l[0]] = v

h = {}
combine(h, l1)
combine(h, l2)
print h

输出:

代码语言:javascript
运行
复制
{'a': {'c': {'gg': {'m': '3'}, 'xx': '4'}, 'b': {'y': '2', 'x': '1'}}}
票数 2
EN

Stack Overflow用户

发布于 2011-04-07 10:17:03

它不是真正的“pythonic”,但我没有看到一个没有递归的好方法

代码语言:javascript
运行
复制
def listToDict(l):
    if type(l) != type([]): return l
    return {l[0] : listToDict(l[1])}
票数 1
EN

Stack Overflow用户

发布于 2011-04-07 12:42:21

对我来说,把这个问题分成两个部分是最有意义的(好吧,我第一次通过..‘s误读了这个问题)

转型

第一部分将[key, list1, list2]数据结构转换为嵌套字典:

代码语言:javascript
运行
复制
def recdict(elements):
    """Create recursive dictionaries from [k, v1, v2, ...] lists.

    >>> import pprint, functools
    >>> pprint = functools.partial(pprint.pprint, width=2)
    >>> pprint(recdict(['a', ['b', ['x', '1'], ['y', '2']]]))
    {'a': {'b': {'x': '1',
                 'y': '2'}}}
    >>> pprint(recdict(['a', ['c', ['xx', '4'], ['gg', ['m', '3']]]]))
    {'a': {'c': {'gg': {'m': '3'},
                 'xx': '4'}}}
    """

    def rec(item):
        if isinstance(item[1], list):
            return [item[0], dict(rec(e) for e in item[1:])]

        return item

    return dict([rec(elements)])

它期待着

  • 每个列表至少有两个元素
  • 每个列表的第一个元素是关键字
  • 如果列表的第二个元素是列表,则所有后续元素也是列表;这些元素将合并到字典中。

棘手的一点(至少对我来说)是意识到您必须从递归函数返回一个列表,而不是字典。否则,您无法组合构成某些列表的第二个和第三个元素的并行列表。

为了使其更具一般性(即对元组和其他序列),我将更改

代码语言:javascript
运行
复制
if isinstance(item[1], list):

代码语言:javascript
运行
复制
if (isinstance(item[1], collections.Sequence)
    and not isinstance(item[1], basestring)):

你也可以让它在任何迭代器上工作,但这需要一点重组。

合并

第二部分合并在两个给定数据结构上运行第一个例程所产生的字典。我认为这将递归地合并任何数量的没有冲突键的字典,尽管除了这个用例之外,我并没有真正测试它。

代码语言:javascript
运行
复制
def mergedicts(*dicts):
    """Recursively merge an arbitrary number of dictionaries.
    >>> import pprint
    >>> d1 = {'a': {'b': {'x': '1',
    ...                   'y': '2'}}}
    >>> d2 = {'a': {'c': {'gg': {'m': '3'},
    ...                   'xx': '4'}}}
    >>> pprint.pprint(mergedicts(d1, d2), width=2)
    {'a': {'b': {'x': '1',
                 'y': '2'},
           'c': {'gg': {'m': '3'},
                 'xx': '4'}}}
    """

    keys = set(k for d in dicts for k in d)

    def vals(key):
        """Returns all values for `key` in all `dicts`."""
        withkey = (d for d in dicts if d.has_key(key))
        return [d[key] for d in withkey]

    def recurse(*values):
        """Recurse if the values are dictionaries."""
        if isinstance(values[0], dict):
            return mergedicts(*values)
        if len(values) == 1:
            return values[0]
        raise TypeError("Multiple non-dictionary values for a key.")

    return dict((key, recurse(*vals(key))) for key in keys)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5575124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档