Create a complicated form of dictionary with try and except

Viewed 50

I have been using list comprehension quite religiously throughout this project and finally I ran into a trouble where some elements do not have the range of index that is required.

Here is my code for better understanding:

result_box_lst = [{
            "coordinates": box['boundingPoly']['normalizedVertices'], 
            "product": [{
                "product_name"  : product["product"]["name"],
                "product_uri"   : product["product"]["img_uri"],
                "price"         : product["product"]["product_price"],
###################### problematic area #############################################
                "product_label1": product["product"]["productLabels"][1]["value"],
                "product_label2": product["product"]["productLabels"][2]["value"],
                "product_label3": product["product"]["productLabels"][3]["value"],
######################################################################################
                "score"         : product["score"]
                } for product in box['results'] if product["score"] >  0.25]
        } for box in grouped_results]

Here, the problem is that sometimes product["product"]["productLables"] does not have multiple elements in the list so the list comprehension crashes with an IndexOutofRange exception. So I was thinking of catching it with try and except and googled it, but alas, list comprehensions can't have try/except within them.

Thus I started coding in the basic way of doing for loop and got stuck wondering how I can create the same structure of complicated dictionary/list using the basic form of for loop. So far, I build this:

result_box_lst = []
product = []
        for box in grouped_results:
            for product in box['results']:
                if product["score"] >  0.25:
                    try:

                    products.append({
                        "product_name": product["product"]["name"],
                        "product_uri"   : product["product"]["img_uri"],
                        "price"         : product["product"]["product_price"],
                        "product_label1": product["product"]["productLabels"][1]["value"],
                        "product_label2": product["product"]["productLabels"][2]["value"],
                        "product_label3": product["product"]["productLabels"][3]["value"],
                        "score"         : product["score"]
                    })

                    except:
                    pass

However, I am quite confident that this will never achieve what I wish. Is there any way to make such complicated dictionary/list with this for loop?

2 Answers

That is a very complex comprehension, so a for loop might end up being more readable and maintainable. But if your only issue is that sometimes your list indices are out of bounds, you can handle that with if / else:

"product_label2": product["product"]["productLabels"][2]["value"] if len(product["product"]["productLabels"]) > 2 else "",
"product_label3": product["product"]["productLabels"][3]["value"] if len(product["product"]["productLabels"]) > 3 else ""

Also, did you deliberately use indices [1] [2] [3] instead of [0] [1] [2]? Just checking...

You could try something like this:

for box in grouped_results:
    for product in box['results']:
        if product["score"] >  0.25:
            data = {
                "product_name": product["product"]["name"],
                "product_uri"   : product["product"]["img_uri"],
                "price"         : product["product"]["product_price"],
                "score"         : product["score"]
            }
            for i in range(1,4):
                if i < len(product["product"]["productLabels"]):
                    data['product_label{}'.format(i)] = product["product"]["productLabels"][i]["value"]
                else:
                    data['product_label{}'.format(i)] = "Some default value"
            products.append(data)

But do note that array starts with 0 so you might need to change a little bit depend on your case

Related