I have a dictionary like below and I want to write a recursive function to return all products:
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': []
}
my function is:
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))
This function ends up with error. can anyone help me find the problem?
CodePudding user response:
You have to iterate like this:
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))
Output:
['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']
CodePudding user response:
A solution that doesn't use recursion. You can just use a queue for this purpose. This would also work no matter how nested your data is.
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))
Output
['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']
CodePudding user response:
You should not access dictionary values by iterating through key-value pairs and matching the keys as it is inefficient and unnecessarily verbose. Access dictionary values directly by keys instead:
def get_product(d):
return [p for s in d['sub_categories'] for p in get_product(s)] d['products']
so that get_product(category)
returns:
['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']