python-3.xsqlitevariablesgloballocal

Is there a way to use locals([eval()]) inside of nested for loops?


I am currently using globals()[eval()] to easily iterate through a database, but when I put this into a function and attempt to use locals() it doesn't properly access the variables.

for fighter in ['1', '2']:
    win = 0
    loss = 0
    for outcome in ['win', 'loss']:
        tko = 0
        sub = 0
        dec = 0
        for method in ['tko', 'sub', 'dec']:
            for rnd in ['1', '2', '3', '4', '5', '6']:
                globals()[eval('outcome')] += fights_fighters_table[
                    'r' + rnd + '_' + method + '_' + outcome + '_' + fighter]
                globals()[eval('method')] += fights_fighters_table[
                    'r' + rnd + '_' + method + '_' + outcome + '_' + fighter]

            # ADD TKO/SUB/DEC WINS/LOSSES TO DATAFRAME
            fights_fighters_table[method + '_' + outcome + '_' + fighter] = globals()[eval('method')]

        globals()[eval('outcome')] += fights_fighters_table['dq_' + outcome + '_' + fighter]

        fights_fighters_table[outcome + '_' + fighter] = globals()[eval('outcome')]

I would like to pass parameters to this code block from a series of other files, so I bellieve that I need to wrap it in a function, but I can't get globals to work within a function and locals() won't access variables outside of the immediate for loop.

I've tried changing all of the globals() calls to locals() expecting it to access any variable within the function, but the eval() returns an empty series.

EDIT: fights_fighters_table row example:

r1_tko_win_1 = 4
r2_tko_win_1 = 2
r3_tko_win_1 = 0
r1_tko_loss_1 = 1
r2_tko_loss_1 = 0
r3_tko_loss_1 = 2
r1_sub_win_1 = 0
r2_sub_win_1 = 1
r2_sub_win_1 = 0
r1_sub_loss_1 = 1
r2_sub_loss_1 = 1
r3_sub_loss_1 = 0

I would like these to add together for each row independently resulting in a dataframe with results like this:

win_1 = 7
loss_1 = 5
tko_win_1 = 6
sub_win_1 = 1
tko_loss_1 = 3
sub_loss_1 = 2

This needs to happen for two fighters in every row.

Table Screenshot:(I don't know a better way to display this) Screenshot section of fights_fighters_table

Modified dataframe to only relevant values:

r1_tko_win_1     3839
r2_tko_win_1     3839
r3_tko_win_1     3839
r4_tko_win_1     3839
r5_tko_win_1     3839
r6_tko_win_1     3839
r1_tko_loss_1    3839
r2_tko_loss_1    3839
r3_tko_loss_1    3839
r4_tko_loss_1    3839
r5_tko_loss_1    3839
r6_tko_loss_1    3839
r1_sub_win_1     3839
r2_sub_win_1     3839
r3_sub_win_1     3839
r4_sub_win_1     3839
r5_sub_win_1     3839
r6_sub_win_1     3839
r1_sub_loss_1    3839
r2_sub_loss_1    3839
r3_sub_loss_1    3839
r4_sub_loss_1    3839
r5_sub_loss_1    3839
r6_sub_loss_1    3839
r1_dec_win_1     3839
r2_dec_win_1     3839
r3_dec_win_1     3839
r4_dec_win_1     3839
r5_dec_win_1     3839
r6_dec_win_1     3839
r1_dec_loss_1    3839
r2_dec_loss_1    3839
r3_dec_loss_1    3839
r4_dec_loss_1    3839
r5_dec_loss_1    3839
r6_dec_loss_1    3839
r1_tko_win_2     3839
r2_tko_win_2     3839
r3_tko_win_2     3839
r4_tko_win_2     3839
r5_tko_win_2     3839
r6_tko_win_2     3839
r1_tko_loss_2    3839
r2_tko_loss_2    3839
r3_tko_loss_2    3839
r4_tko_loss_2    3839
r5_tko_loss_2    3839
r6_tko_loss_2    3839
r1_sub_win_2     3839
r2_sub_win_2     3839
r3_sub_win_2     3839
r4_sub_win_2     3839
r5_sub_win_2     3839
r6_sub_win_2     3839
r1_sub_loss_2    3839
r2_sub_loss_2    3839
r3_sub_loss_2    3839
r4_sub_loss_2    3839
r5_sub_loss_2    3839
r6_sub_loss_2    3839
r1_dec_win_2     3839
r2_dec_win_2     3839
r3_dec_win_2     3839
r4_dec_win_2     3839
r5_dec_win_2     3839
r6_dec_win_2     3839
r1_dec_loss_2    3839
r2_dec_loss_2    3839
r3_dec_loss_2    3839
r4_dec_loss_2    3839
r5_dec_loss_2    3839
r6_dec_loss_2    3839

Solution

  • I believe you can get rid of all the global() and eval() stuff if you use a dictionary to hold your summations.

    See if this gets you going again in a direction you can work with.

    
    ## --------------------------
    ## Rows of tuples from a database
    ## --------------------------
    fights_fighters_table = [
        ("r1_tko_win_1", 4),
        ("r2_tko_win_1", 2),
        ("r3_tko_win_1", 0),
        ("r1_tko_loss_1", 1),
        ("r2_tko_loss_1", 0),
        ("r3_tko_loss_1", 2),
        ("r1_sub_win_1", 0),
        ("r2_sub_win_1", 1),
        ("r2_sub_win_1", 0),
        ("r1_sub_loss_1", 1),
        ("r2_sub_loss_1", 1),
        ("r3_sub_loss_1", 0)
    ]
    ## --------------------------
    
    ## --------------------------
    ## total up the various values for newly constructed keys
    ## based on the components of the key for the given row
    ## --------------------------
    totals = {}
    for key, value in fights_fighters_table:
        fight_round, method, outcome, fighter = key.split("_")
    
        new_key = f"{outcome}_{fighter}"
        totals[new_key] = totals.get(new_key, 0) + value
    
        new_key = f"{method}_{outcome}_{fighter}"
        totals[new_key] = totals.get(new_key, 0) + value
    ## --------------------------
    
    import json
    print("Summary:")
    print(json.dumps(totals, indent=4))
    

    That should give you:

    Summary:
    {
        "win_1": 7,
        "tko_win_1": 6,
        "loss_1": 5,
        "tko_loss_1": 3,
        "sub_win_1": 1,
        "sub_loss_1": 2
    }
    

    Ultimately, if this does help you, it might be closed as a duplicate of:

    How do I create variable variables?