Home > Enterprise >  Doing calculations while creating a List (in Python)
Doing calculations while creating a List (in Python)

Time:07-13

I'm getting data from an API and storing it on Python dictionary (and then a list of dictionaries).

I need to do calculations (max, sum, divisions...) on the dictionary data to create extra data to add to the same dictionary/list.

My current code looks like this:

stream = whatever (whatever, whatever)
keywords = []

for batch in stream:
    for row in batch.results:

        max_clicks = max(data_keywords["keywords_clicks"])
        weighted_clicks = sum(data_keywords["keywords_weighted"])/sum(data_keywords["keywords_clicks"])

        data_keywords = {}
        data_keywords["keywords_text"] = row.ad_group_criterion.keyword.text
        data_keywords["keywords_clicks"] = row.metrics.clicks  
        data_keywords["keywords_conversion_rate"] = row.metrics.conversions_from_interactions_rate
        data_keywords["keywords_weighted"] = row.metrics.clicks * row.metrics.conversions_from_interactions_rate  
        data_keywords["etv"] = (data_keywords["keywords_clicks"]/max_clicks*data_keywords["keywords_conversion_rate"]) ((1-data_keywords["keywords_clicks"]/max_clicks)*weighted_clicks)
        keywords.append(data_keywords)

This doesn't work, it gives UnboundLocalError (local variable 'data_keywords' referenced before assignment). I've tried different options and got different errors.

data_keywords["etv"] is what I want to calculate ("max_clicks", "weighted_clicks" and data_keywords["keywords_weighted"] are intermediate calculations for that)

The main problem is that I need to calculate max and sum for all values inside the dictionary, then do a calculation using that max and sum for each value and then store the results in the dictionary itself.

So I don't know where to put the code to do the calculations (before the dictionary, inside the dictionary, after the dictionary or a mix)

I guess it should be possible, but I'm a Python/programming newbie and can't figure this out.

It's probably not relevant, but in case you are wondering, I'm trying to create a weighted sort (https://moz.com/blog/build-your-own-weighted-sort). And I can't use models/database to store data.

Thanks!

CodePudding user response:

You can't refer to elements of the dictionary before you create it. Move those variable assignments down to after you assign the dictionary elements.

for batch in stream:
    for row in batch.results:
        data_keywords = {}
        data_keywords["keywords_text"] = row.ad_group_criterion.keyword.text
        data_keywords["keywords_clicks"] = row.metrics.clicks  
        data_keywords["keywords_conversion_rate"] = row.metrics.conversions_from_interactions_rate
        data_keywords["keywords_weighted"] = row.metrics.clicks * row.metrics.conversions_from_interactions_rate  

        max_clicks = max(data_keywords["keywords_clicks"])
        weighted_clicks = sum(data_keywords["keywords_weighted"])/sum(data_keywords["keywords_clicks"])

        data_keywords["etv"] = (data_keywords["keywords_clicks"]/max_clicks*data_keywords["keywords_conversion_rate"]) ((1-data_keywords["keywords_clicks"]/max_clicks)*weighted_clicks)
        keywords.append(data_keywords)

CodePudding user response:

The UnboundLocalError is because you are trying to access data_keywords["keywords_clicks"] before you have declared data_keywords or set the value for "keywords_clicks".

Also, I think you need to be clearer about what data structure you are trying to create. You mention "a list of dictionaries" which I don't see. Maybe you are trying to create a dictionary of lists, but it looks like you overwrite the dictionary values each time you go through your loop.

CodePudding user response:

adding my response as an answer, as I do not have enough reputation to comment

To get rid of assignment error just move the line data_keywords = {} above max_clicks = max(data_keywords["keywords_clicks"])

Here you are trying to access a local variable before its declaration. The code in this case is trying to access a global variable which doesn't seems to exist.

stream = whatever (whatever, whatever) 
keywords = []

for batch in stream:
 for row in batch.results:    
    data_keywords = {}
    max_clicks = max(data_keywords["keywords_clicks"])
    weighted_clicks = sum(data_keywords["keywords_weighted"])/sum(data_keywords["keywords_clicks"])

    data_keywords["keywords_text"] = row.ad_group_criterion.keyword.text
    data_keywords["keywords_clicks"] = row.metrics.clicks  
    data_keywords["keywords_conversion_rate"] = row.metrics.conversions_from_interactions_rate
    data_keywords["keywords_weighted"] = row.metrics.clicks * row.metrics.conversions_from_interactions_rate  
    data_keywords["etv"] = (data_keywords["keywords_clicks"]/max_clicks*data_keywords["keywords_conversion_rate"]) ((1-data_keywords["keywords_clicks"]/max_clicks)*weighted_clicks)
    keywords.append(data_keywords)

More on that here

  • Related