【问题标题】:get a nested dictionary items recursively递归获取嵌套字典项
【发布时间】:2021-11-01 11:09:41
【问题描述】:

我有一个像下面这样的字典,我想编写一个递归函数来返回所有产品:

category = {'name': 'electronic_devices',
            'sub_categories': [
                {
                    'name': 'mobile-phone',
                    'sub_categories': [],
                    'products': [
                        'Sony xperia 1'
                        'Samsung Galaxy A32',
                        'Apple iphone 12',
                        'Xiaomi redmi 9'
                    ]
                },
                {
                    'name': 'laptop',
                    'sub_categories': [
                        {
                            'name': 'ultrabook',
                            'sub_categories': [],
                            'products': [
                                'Asus ROG strix',
                                'Microsoft surface book 3',
                                'Lenovo ideapad 3'
                            ]
                        }
                    ],
                    'products': [
                        'Dell inspiron 3583-5278',
                        'HP pavilion dk1056wm'
                    ]
                }
            ],
            'products': []
            } 

我的功能是:

def get_product(dic):
    for k, v in dic.items():
        if k == 'sub_categories':
            return get_product(k)
        elif k == 'products':
            return v
   
print(get_product(category))

此函数以错误结束。 谁能帮我找出问题?

【问题讨论】:

    标签: python function dictionary recursion nested


    【解决方案1】:

    你必须像这样迭代:

    def get_product(dic):
        x = []
        for k, v in dic.items():
            if k == 'sub_categories':
                for i in v:
                    x.extend(get_product(i))
            elif k == 'products':
                x.extend(v)
        return x
       
    print(get_product(category))
    

    输出:

    ['Sony xperia 1Samsung Galaxy A32', 'Apple iphone 12', 'Xiaomi redmi 9', 'Asus ROG strix', 'Microsoft surface book 3', 'Lenovo ideapad 3', 'Dell inspiron 3583-5278', 'HP pavilion dk1056wm']
    

    【讨论】:

    • 这并没有回答问题,尽管它很接近,因为他们专门要求 all 产品,而这只返回第一个子类别中的产品。然而,这绝对是在正确的轨道上。
    • @AlexanderHuszagh 哦,对,编辑了我的答案,现在应该可以使用了
    • 它只返回第一个产品而不是所有产品
    • @YasamanShokri 它已经被修改为正确答案,所以它按照问题中的要求进行操作^_^。
    • @YasamanShokri 好吧,在这种情况下,更有效和更整洁的方法是使用 for 循环,我认为没有 for 循环就没有办法。 :)
    【解决方案2】:

    不使用递归的解决方案。您可以为此目的使用队列。无论您的数据有多嵌套,这也可以工作。

    category = {
        'name': 'electronic_devices',
        'sub_categories': [
            {
                'name': 'mobile-phone',
                'sub_categories': [],
                'products': [
                    'Sony xperia 1',
                    'Samsung Galaxy A32',
                    'Apple iphone 12',
                    'Xiaomi redmi 9'
                ]
            },
            {
                'name': 'laptop',
                'sub_categories': [
                    {
                        'name': 'ultrabook',
                        'sub_categories': [
                            {
                                'products': [
                                    'Laser sword',
                                    'Beyblade',
                                    'Crush Gear'
                                ]
                            }
                        ],
                        'products': [
                            'Asus ROG strix',
                            'Microsoft surface book 3',
                            'Lenovo ideapad 3'
                        ]
                    }
                ],
                'products': [
                    'Dell inspiron 3583-5278',
                    'HP pavilion dk1056wm'
                ]
            }
        ],
        'products': ["Solar System Destructor Beta-3A"]
    }
    
    def get_products(dic):
        products = []
        queue = [dic]
        
        while queue:
            data = queue.pop()
            if isinstance(data, dict):
                products.extend(data.get('products', []))
                queue.extend(data.values())
            elif isinstance(data, list):
                queue.extend(data)
    
        return products
    
    print(get_products(category))
    

    输出

    ['Solar System Destructor Beta-3A', 'Dell inspiron 3583-5278', 'HP pavilion dk1056wm', 'Asus ROG strix', 'Microsoft surface book 3', 'Lenovo ideapad 3', 'Laser sword', 'Beyblade', 'Crush Gear', 'Sony xperia 1', 'Samsung Galaxy A32', 'Apple iphone 12', 'Xiaomi redmi 9']
    

    【讨论】:

      【解决方案3】:

      您不应该通过遍历键值对和匹配键来访问字典值,因为它效率低且不必要地冗长。而是直接通过键访问字典值:

      def get_product(d):
          return [p for s in d['sub_categories'] for p in get_product(s)] + d['products']
      

      这样get_product(category) 返回:

      ['Sony xperia 1Samsung Galaxy A32', 'Apple iphone 12', 'Xiaomi redmi 9', 'Asus ROG strix', 'Microsoft surface book 3', 'Lenovo ideapad 3', 'Dell inspiron 3583-5278', 'HP pavilion dk1056wm']
      

      【讨论】:

        猜你喜欢
        • 2022-06-23
        • 1970-01-01
        • 2021-12-04
        • 2017-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多