Python嵌套字典从嵌套值检索键

时间:2020-06-11 21:15:51

标签: python python-3.x loops dictionary recursion

我有一个Python字典,字典中大量嵌套。有几层。

我要完成的功能是可以输入“子类别”值中的任何一个,例如20003482或200000879,并且它必须返回第一个嵌套的子类别关键字,因此对于上述示例,100003109 < / p>

我不确定执行此操作的最佳方法,但是我已经尝试过类似的方法

        group = [k for k, v in category_groups.items() if c1 in v][0]

而且这似乎只适用于第一层嵌套

这里是否有通用的递归解决方案?最好的方法是什么

cat_list = {
  1: {
    'name': 'Clothing & Accessories',
    'subcategories': {
      100003109: {
        'name': "Women's Clothing",
        'image': '/images/vectors/niche/womens.jpg',
        'description': 'Womens Dresses, Blouses, Hoodies, Sweaters, Jackets, Leggings & Much More',
        'winning': True,
        'subcategories': {
          200003482: {
            'winning': False,
            'name': 'Dresses',
            'subcategories': {}
          },
          200001648: {
            'winning': False,
            'name': 'Blouses & Shirts',
            'subcategories': {}
          },
          100003141: {
            'winning': False,
            'name': 'Hoodies & Sweatshirts',
            'subcategories': {}
          },
          200000783: {
            'name': 'Sweaters',
            'winning': True,
            'subcategories': {
              200000879: {
                'name': 'Pullovers'
              },
              200000877: {
                'name': 'Cardigans'
              },
              200000882: {
                'name': 'Vests'
              },
              200000881: {
                'name': 'Shrugs'
              },
              200217993: {
                'name': 'Cloak'
              }
            }
          },
        }
      },
      100003070: {
        'name': "Men's Clothing",
        'image': '/images/vectors/niche/mens.jpg',
        'description': 'Mens Hoodies, T-Shirts, Jackets, Jeans, Suits & Much More',
        'winning': False,
        'subcategories': {
          100003084: {
            'winning': True,
            'name': 'Hoodies & Sweatshirts',
            'subcategories': {}
          },
          200000707: {
            'name': 'Tops & T-Shirts',
            'winning': False,
            'subcategories': {
              200000717: {
                'name': 'Tank Tops'
              },
              200010062: {
                'name': 'Polo Shirts'
              },
              100003071: {
                'name': 'T-Shirts'
              }
            }
          },
        }
      },
  },
  2: {
    'name': 'Electronics',
    'subcategories': {
      509: {
        'name': 'Phones',
        'image': '/images/vectors/niche/mobile.jpg',
        'description': 'iPhone & Android Accessories, Cases, Chargers',
        'winning': False,
        'subcategories': {
          200084017: {
            'winning': False,
            'name': 'Mobile Phone Accessories',
            'subcategories': {
              200003189: {
                'name': 'Mobile Phone Lenses'
              },
              200003130: {
                'name': 'Armbands'
              },
              200003132: {
                'name': 'Power Bank'
              },
              200003089: {
                'name': 'Phone Screen Protectors'
              },
              200217751: {
                'name': 'Wireless Chargers'
              },
              200217746: {
                'name': 'Car Chargers'
              },
              100003569: {
                'name': 'Mobile Phone Cables'
              },
              100003571: {
                'name': 'Mobile Phone Chargers'
              },
              5093005: {
                'name': 'Mobile Phone Straps'
              },
              5093004: {
                'name': 'Mobile Phone Holders & Stands'
              },
              5093006: {
                'name': 'Mobile Phone Adapters'
              },
              5093001: {
                'name': 'Mobile Phone Stickers'
              }
            }
          },
          200216959: {
            'winning': False,
            'name': 'Phone Bags & Cases',
            'subcategories': {
              200215191: {
                'name': 'Battery Charger Cases'
              },
              200216972: {
                'name': 'Wallet Cases'
              },
              200216991: {
                'name': 'Phone Bumper Cases'
              },
              200216981: {
                'name': 'Fitted Cases'
              },
              200216980: {
                'name': 'Phone Pouches'
              },
              200216978: {
                'name': 'Rhinestone Cases'
              },
              200216977: {
                'name': 'Flip Cases'
              },
              200217991: {
                'name': 'Slim Cases'
              }
            }
          }
        }
      },
      7: {
        'name': 'Computers',
        'image': '/images/vectors/niche/computer.jpg',
        'description': 'Tablet & Office Gadgets, 3D Printing Pens, Computer Peripherals & Cleaners. Laptop Accessories.',
        'winning': False,
        'subcategories': {
          200004720: {
            'winning': True,
            'name': 'Office Electronics',
            'subcategories': {
              2107: {
                'name': 'Projectors'
              },
              200138005: {
                'name': '3D Pens'
              },
              200042003: {
                'name': '3D Printers'
              },
              200140003: {
                'name': '3D Printing Materials'
              }
            }
          },
          200002361: {
            'winning': False,
            'name': 'Tablet Accessories',
            'subcategories': {
              200002368: {
                'name': 'Tablet Touch Pens'
              },
              200002365: {
                'name': 'Tablet Stickers'
              },
              200002364: {
                'name': 'Tablet Cases'
              },
              200002624: {
                'name': 'Tablet Stands'
              },
              200003724: {
                'name': 'Tablet Screen Protectors'
              }
            }
          },
          200002342: {
            'winning': False,
            'name': 'Computer Peripherals',
            'subcategories': {
              708024: {
                'name': 'Keyboard & Mouse Sets'
              },
              708023: {
                'name': 'Mouse Pads'
              },
              708032: {
                'name': 'USB Docks & Hubs'
              },
              70802: {
                'name': 'Keyboards'
              },
              70805: {
                'name': 'Mice'
              },
              7171: {
                'name': 'USB Gadgets'
              }
            }
          },
          708022: {
            'winning': False,
            'name': 'Computer Cleaners',
            'subcategories': {}
          },
          100005063: {
            'winning': True,
            'name': 'Laptop Accessories',
            'subcategories': {
              200002360: {
                'name': 'Laptop Desks'
              },
              721: {
                'name': 'Laptop Cooling Pads'
              },
              380110: {
                'name': 'Laptop Bags & Cases'
              },
              708031: {
                'name': 'Laptop Skins & Stickers'
              },
              708021: {
                'name': 'Keyboard Covers'
              },
              200216761: {
                'name': 'Laptop Stand'
              }
            }
          }
        }
      },
      44: {
        'name': 'Gadgets',
        'image': '/images/vectors/niche/electronics.jpg',
        'description': 'Camera Accessories & Lighting, Selfie Sticks, Earphones & Headphones, Smart Watches, E-Cigs & Vapes, Gaming Accessories, Speakers & Solar Gadgets',
        'winning': False,
        'subcategories': {
          200002395: {
            'winning': True,
            'name': 'Camera & Photo',
            'subcategories': {
              200002411: {
                'name': 'Photographic Lighting'
              },
              200002408: {
                'name': 'Tripod & Accessories'
              },
              200002413: {
                'name': 'Mini Camcorders'
              },
              200216548: {
                'name': 'Tabletop Shooting'
              },
              1901: {
                'name': 'Film Camera'
              },
              1903: {
                'name': 'Camera & Photo Accessories'
              },
              200216669: {
                'name': 'Selfie Sticks'
              },
              200216611: {
                'name': 'Flashes & Accessories'
              }
            }
          },
          200002398: {
            'winning': True,
            'name': 'Portable Audio & Video',
            'subcategories': {
              200003109: {
                'name': 'Earphone Accessories'
              },
              200217778: {
                'name': 'Translator'
              },
              63705: {
                'name': 'Earphones & Headphones'
              },
              63708: {
                'name': 'Microphones'
              }
            }
          },
          200010196: {
            'winning': True,
            'name': 'Smart Electronics',
            'subcategories': {
              200086023: {
                'name': 'Smart Home Electronics'
              },
              200010206: {
                'name': 'Smart Watches'
              }
            }
          },
          200002394: {
            'winning': False,
            'name': 'Accessories & Parts',
            'subcategories': {
              200084029: {
                'name': 'Smart Power Sockets & Plugs'
              },
              200003200: {
                'name': 'Tech Cables & Accessories'
              },
              200003127: {
                'name': 'Cable Winders & Protectors'
              },
              380210: {
                'name': 'Camera/Video Bags'
              }
            }
          },
          200005280: {
            'winning': False,
            'name': 'Electronic Cigarettes & Vapes',
            'subcategories': {
              200005289: {
                'name': 'Electronic Cigarette Mods'
              },
              200005288: {
                'name': 'Elctronic Cigarette Chargers'
              },
              200005282: {
                'name': 'Electronic Cigarette Accessories'
              },
              200005281: {
                'name': 'Electronic Cigarette Kits'
              },
              200005287: {
                'name': 'Electronic Cigarette Batteries'
              },
              200005285: {
                'name': 'Electronic Cigarette Atomizers'
              },
              200005284: {
                'name': 'Eletronic Cigarette Atomizer Cores'
              }
            }
          },
          200002396: {
            'winning': False,
            'name': 'Video Games',
            'subcategories': {
              200215241: {
                'name': 'Stands'
              },
              200215236: {
                'name': 'Screen Protectors'
              },
              200215208: {
                'name': 'Joysticks'
              },
              200215202: {
                'name': 'Cases'
              },
              200215201: {
                'name': 'Bags'
              },
              200215228: {
                'name': 'Handheld Game Players'
              },
              200215227: {
                'name': 'Gamepads'
              },
              200215197: {
                'name': 'Chargers'
              },
              200004542: {
                'name': 'Video Games Wheels'
              }
            }
          },
          200216623: {
            'winning': True,
            'name': 'Earphones & Headphones',
            'subcategories': {
              200216686: {
                'name': 'Earphones'
              },
              200216605: {
                'name': 'Headphone/Headset'
              },
              200216593: {
                'name': 'Bluetooth Earphones & Headphones'
              }
            }
          },
          200084019: {
            'winning': True,
            'name': 'Wearable Devices',
            'subcategories': {
              200010211: {
                'name': 'Smart Accessories'
              },
              200010209: {
                'name': 'Smart Activity Trackers'
              },
              200010207: {
                'name': 'Smart Wristbands'
              },
              200010206: {
                'name': 'Smart Watches'
              }
            }
          },
          200215272: {
            'winning': False,
            'name': 'VR/AR Devices',
            'subcategories': {
              100007533: {
                'name': '3D Glasses/ Virtual Reality Glasses'
              }
            }
          },
          200216592: {
            'winning': False,
            'name': '360° Video Cameras & Accessories',
            'subcategories': {
              200215271: {
                'name': '360° Video Camera'
              }
            }
          },
          200217534: {
            'winning': False,
            'name': 'Speakers',
            'subcategories': {
              518: {
                'name': 'Portable Speakers'
              },
              200217564: {
                'name': 'Subwoofer'
              },
              200217561: {
                'name': 'Soundbar'
              }
            }
          },
          200218547: {
            'winning': False,
            'name': 'Solar Gadgets',
            'subcategories': {
              200218548: {
                'name': 'Solar'
              }
            }
          }
        }
      }
    }
  },
  }
}

就示例而言,应该发生以下情况:

输入10003109、200003482或200000879,将得到键10003109的值。

输入100003070、100003084或200000717将产生键100003070的值

输入509、200084017或200215241应该得到键509的值

3 个答案:

答案 0 :(得分:0)

可能有2种不同的解决方案。比较简单的一种是在这里,您知道子类别在固定深度处,在这种情况下

cat_list[n]['subcategories'][upper_item]['subcategories'][lower_item]

这可以通过嵌套循环来解决。我会使用for循环来编写它,一旦工作,就可以转换为列表理解。

第二种更复杂的方法是使用递归的任意级别。应该不太难。

答案 1 :(得分:0)

您可以执行以下操作:

def get_key(nested_dictionary, thing):
    for key, value in nested_dictionary.items():
        if type(value) is dict:
            if key == thing:
                print(value)
            get_key(value, thing)
        else:
            if key == thing:
                print(value)

您可以在打印处返回该函数,也可以将其附加到列表等中。如果需要澄清其工作原理,可以发表评论,我会回答:)

答案 2 :(得分:0)

有些事情吗?您可能想对其进行重构并用多个案例进行测试,我只尝试了您提到的案例,但这足以使您走上正轨

def get_subcategory_high_level(cat_list, subcategory_id):
    for k, category in cat_list.items():
        first_key = get_subcategory(category, subcategory_id)
        if first_key:
            return first_key


def get_subcategory(cat_list, subcategory_id):
    if "subcategories" in cat_list:
        for k, v in cat_list['subcategories'].items():
            if subcategory_id == k:
                return k
            else:
                match = get_subcategory(v, subcategory_id)
                if match:
                    return k