简体   繁体   English

Python:将元组列表转换为嵌套字典字典

[英]Python: Turn List of Tuples into Dictionary of Nested Dictionaries

so I have a bit of an issue on my hands.所以我手头有点问题。 I have a list of tuples (made up of a level number and message) which will eventually become an HTML list.我有一个元组列表(由级别编号和消息组成),最终将成为一个 HTML 列表。 My issues is that before this happens, I would like to turn the tuples values into a dictionary of nested dictionaries.我的问题是,在这发生之前,我想将元组值转换为嵌套字典的字典。 So here is the example:所以这里是例子:

# I have this list of tuples in format of (level_number, message)
tuple_list = [(1, 'line 1'), (2, 'line 2'), (3, 'line 3'), (1, 'line 4')]

# And I want to turn it into this
a_dict = {
    'line 1': {
        'line 2': {
            'line 3': {}
        }
    }, 
    'line 4': {}
}

Any help would be appreciated, as long as it is valid Python 3. Thanks!任何帮助将不胜感激,只要它是有效的 Python 3。谢谢!

As I pointed out in a comment, you should STRONGLY consider changing your incoming data structure if you have any control at all over it.正如我在评论中指出的那样,如果您有任何控制权,您应该强烈考虑更改传入的数据结构。 A sequential list of tuples is definitely not ideal for what you're doing here.元组的顺序列表绝对不适合您在此处执行的操作。 However it is possible if you treat it like a tree.然而,如果你把它当作一棵树来对待,这是可能的。 Let's build a (sane) data structure to parse this with让我们构建一个(理智的)数据结构来解析它

class Node(object):
    def __init__(self, name, level, parent=None):
        self.children = []
        self.name = name
        self.level = level
        self.parent = parent

    def make_child(self, othername, otherlevel):
        other = self.__class__(othername, otherlevel, self)
        self.children.append(other)
        return other

Now you should be able to iterate over your data structure in some sensible way现在您应该能够以某种合理的方式迭代您的数据结构

def make_nodes(tuple_list):
    """Builds an ordered grouping of Nodes out of a list of tuples
    of the form (level, name). Returns the last Node.
    """

    curnode = Node("root", level=-float('inf'))
    # base Node who should always be first.

    for level, name in tuple_list:
        while curnode.level >= level:
            curnode = curnode.parent
            # if we've done anything but gone up levels, go
            # back up the tree to the first parent who can own this
        curnode = curnode.make_child(name, level)
        # then make the node and move the cursor to it
    return curnode

Once your structure is complete, you can iterate on it.一旦您的结构完成,您就可以对其进行迭代。 Doesn't much matter here if you go depth-first or breadth-first, so let's do a DFS just for ease of implementation.如果您采用深度优先或广度优先,这里并不重要,所以让我们做一个 DFS 只是为了便于实现。

def parse_tree(any_node):
    """Given any node in a singly-rooted tree, returns a dictionary
    of the form requested in the question
    """

    def _parse_subtree(basenode):
        """Actually does the parsing, starting with the node given
        as its root.
        """

        if not basenode.children:
            # base case, if there are no children then return an empty dict
            return {}
        subresult = {}
        for child in basenode.children:
            subresult.update({child.name: _parse_subtree(child)})
        return subresult

    cursor = any_node
    while cursor.parent:
        cursor = cursor.parent
        # finds the root node
    result = {}
    for child in cursor.children:
        result[child.name] = _parse_subtree(child)
    return result

Then feed in your tuple list et voila然后输入你的元组列表等等

tuple_list = [(1, 'line 1'), (2, 'line 2'), (3, 'line 3'), (1, 'line 4')]

last_node = make_nodes(tuple_list)
result = parse_tree(last_node)
# {'line 1': {'line 2': {'line 3': {}}}, 'line 4': {}}

Assuming you only have three levels, something like following would do:假设您只有三个级别,则可以执行以下操作:

tuple_list = [(1, 'line 1'), (2, 'line 2'), (3, 'line 3'), (1, 'line 4')]

a_dict = {}

for prio, key in tuple_list:
    if prio == 1:
        a_dict[key] = {}
        first_level = key
    if prio == 2:
        a_dict[first_level][key] = {}
        second_level = key
    if prio == 3:
        a_dict[first_level][second_level][key] = {}
    # So on ...
print a_dict

This also assumes that hierarchies are listed in order, meaning level 1, level 1', level 2, level 3 would be a single dict for level 1, and a hierarchal order like level 1' -> level 2 -> level 3. So the following这也假设层次结构按顺序列出,这意味着级别 1、级别 1'、级别 2、级别 3 将是级别 1 的单个 dict,以及级别顺序,如级别 1' -> 级别 2 -> 级别 3。所以下列

tuple_list = [(1, 'line 5'), (1, 'line 1'), (2, 'line 2'), (3, 'line 3'), (1, 'line 4')]

Would yield the following :将产生以下结果:

{'line 1': {'line 2': {'line 3': {}}}, 'line 4': {}, 'line 5': {}}

Or a little more complicated:或者稍微复杂一点:

tuple_list = [(1, 'line 1'), (2, 'line 2'), (2, 'line 6'), (3, 'line 3'), (3, 'line 7'), (1, 'line 4'), (1, 'line 5')]

would yield会屈服

{'line 1': {'line 2': {}, 'line 6': {'line 3': {}, 'line 7': {}}}, 'line 4': {}, 'line 5': {}}

Since your levels are not limited to a small number, it's not a good approach to just do it through plain IFs .由于您的级别不限于少数,因此仅通过普通 IF 来完成它不是一个好方法 It's better to construct a tree, then traverse the tree and create the representation you want.最好先构建一棵树,然后遍历树并创建您想要的表示。 Doing so is also easy, you have several root nodes (where parent=None), each one has a list of children and this repeats for the children, so you have a tree.这样做也很容易,您有多个根节点(其中 parent=None),每个根节点都有一个子节点列表,并且对子节点重复此操作,因此您有一个树。 You now start from the root and make the ordering you want !您现在从根开始并进行所需的排序!

It's easily implementable and I guess you get the idea !它很容易实现,我想你明白了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM