Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:从父子值列表创建嵌套字典_Python_Python 3.x_Dictionary_Treeview - Fatal编程技术网

Python:从父子值列表创建嵌套字典

Python:从父子值列表创建嵌套字典,python,python-3.x,dictionary,treeview,Python,Python 3.x,Dictionary,Treeview,以下是输入: list_child_parent= [ #first value is child, second is parent (0, 1), (1, 3), (8, 7), (3, 6), (4, 3), (5, 3) ] 输出需要使用这些值创建嵌套字典树。树的深度永远不会超过6层 例如: output_dict = { 6: {3: {1: {0: {}}, 4: {}, 5: {}}}, 7: {8: {}} }

以下是输入:

list_child_parent= [
    #first value is child, second is parent
    (0, 1),
    (1, 3),
    (8, 7),
    (3, 6),
    (4, 3),
    (5, 3)
]
输出需要使用这些值创建嵌套字典树。树的深度永远不会超过6层

例如:

output_dict = {
    6: {3: {1: {0: {}}, 4: {}, 5: {}}}, 7: {8: {}}
}
我花了两天的时间来完成这项工作。我曾尝试编写函数来查找键在树中的位置,然后在其后添加新键,但我无法生成可以继续超过3个级别的代码。这是令人困惑的,我觉得可能有一个标准库可以做到这一点


我的经验水平很低

不太好看,可能也不太像蟒蛇,但它应该能让你行动起来:

#!/usr/bin/env python3

def make_map(list_child_parent):
    has_parent = set()
    all_items = {}
    for child, parent in list_child_parent:
        if parent not in all_items:
            all_items[parent] = {}
        if child not in all_items:
            all_items[child] = {}
        all_items[parent][child] = all_items[child]
        has_parent.add(child)

    result = {}
    for key, value in all_items.items():
        if key not in has_parent:
            result[key] = value
    return result

if __name__ == '__main__':
    list_child_parent = [
        #first value is child, second is parent
        (0, 1),
        (1, 3),
        (8, 7),
        (3, 6),
        (4, 3),
        (5, 3)
    ]

    actual = make_map(list_child_parent)

    expected = {
        6: {
            3: {
                1: {
                    0: {}
                },
                4: {},
                5: {}
            }
        },
        7: {
            8: {}
        }
    }
    print('OK' if expected == actual else 'FAIL')

此代码将树从给定格式转换为树结构字典。这是一个很大的失误,但它有助于跟踪正在发生的事情。就性能而言,它相当不错

LIST_CHILD_PARENTS = [                                                     
#first value is child, second is parent                                    
(0, 1),                                                                    
(1, 3),                                                                    
(8, 7),                                                                    
(3, 6),                                                                    
(4, 3),                                                                    
(5, 3)                                                                     
]                                                                          


class Node(object):                                                        
    def __init__(self, value):                    
        self.value = value
        # List of references to Node()'s.                                                
        self.child = []              
        # Reference to parent Node()                                                                           
        self.parent = None                                               
    def set_parent(self, parent):                                          
        self.parent = parent                                               
    def set_child(self, child):                                            
        self.child.append(child)                                           


def get_a_root(items):                                                     
    """Find a root node from items.                                        

    Grab some node and follow the parent pointers to a root.               
    """                                                                    
    cur_key = list(items.keys())[0]                                              
    while items[cur_key].parent is not None:                               
        cur_key = items[cur_key].parent.value                              
    parent = items[cur_key]                                                
    return parent                                                          

def extract_tree(items, root):                                             
    """Remove the tree from root in items.                                 
    """                                                                    
    cur_key = root.value                                                   
    this_node = items[cur_key]                                             
    if len(this_node.child) == 0:                                          
        items.pop(cur_key)                                                 
        return                                                             
    else:                                                                  
        for child in this_node.child:                                      
            extract_tree(items, child)                                     
        items.pop(cur_key)                                                  

def insert_from_root(tree, root):                                          
    """Insert the dictionary items from a tree.                            
    """                                                                    
    current = root                                                         
    if len(current.child) == 0:                                            
        tree[current.value] = {}                                           
        return                                                             
    else:                                                                  
        table = {}                                                         
        for child in current.child:                                        
            insert_from_root(table, child)                                 
        tree[current.value] = table                                                                                                

def build_graphs():                                                        
    """Map all input graphs into Node(object)'s.           

    Return: A hash table by value: Node(value, child, parent)              
    """                                                                    
    items = {}                                                             
    for child, parent in LIST_CHILD_PARENTS:                               
        if not child in items:                                       
            c_n = Node(child)  
            items[child] = c_n                 
        else:                                                              
            c_n = items[child]                                             
        if not parent in items:                                      
            p_n = Node(parent) 
            items[parent] = p_n                    
        else:                                                              
            p_n = items[parent]                                            
        p_n.set_child(c_n)                                                 
        c_n.set_parent(p_n)                                                                                       
    return items                                                           

def run_dict_builder():                                                    
    """Map the graphs from input and map into a dict.                                  

    Sequence:                                                              
        1- Map all graphs from input trees: list(tuple)             
        2- For each root node:                                             
            2A - Get a root node.                                      
            2B - Extract tree under this root from graphs list.                  
            2C - Insert the tree from this root into dict.                      
        3- Return the Dictionary Tree structure.                                                     
    """                                                                    
    graphs = build_graphs()                                                

    h_table = {}                                                           
    while len(graphs) > 0:                                                 
        root = get_a_root(graphs)                                          
        extract_tree(graphs, root)                                
        insert_from_root(h_table, root)                          
    return h_table                                                         

print(run_dict_builder())

根据您的“示例输出”,3是8的父项。但这不是你的输入所描述的。此外,8不是应该是7岁的孩子吗?我很困惑。
键:value
对有模式吗?3是1、4和5的父项。是的,8岁是7岁的孩子,我解决了这个问题。显然,我还没有生成输出的代码,所以我手工编写了字典。这对字典没有模式。您应该假设父子巢穴的列表可以是任意顺序。您的树不应该是
{6:{3:{1:{0:{},4:{},5:{},7:{8:{}}
?您显示3在元组中有children 1、5、4,但输出使1看起来像是有childs 5、4、0。此解决方案工作得非常好。它将我45行不起作用的代码浓缩成一个简单易懂的解决方案。我以前从未见过set()以这种方式使用,在阅读python文档之后,您的用法就不那么明显了。我应该注意,一旦构建了树,它就会保存在缓存中,因此性能不是问题。但是,有数千个父/子关系,并且在添加新数据时需要定期重建树。这可能会作为我正在构建的flask网站的cron运行。你能帮我反向操作吗,即从同一嵌套字典生成父-子对?@user3156040答案可能不适合评论。请你提出一个新问题,然后在这里发布链接,好吗?马特,谢谢你提供了一个非常好的解决方案。这是可行的,但我需要在Python3环境中使用它(应该指定-抱歉!)。如何更改第67行的items.has_键以使其与python 3一起工作<代码>属性错误:“dict”对象没有属性“has_key”@dansafe您可以使用:
如果项目中的父项:
<代码>如果输入dict: