Search code examples
pythonpython-3.xdictionarycounter

Why do two global dictionaries interacting in Python throw a local reference error?


When I use two global dictionaries (in my case, Counters) that interact, Python throws a local reference error. To illustrate the issue, here is sample code:

from collections import Counter

hourly_detections = Counter()
daily_detections = Counter()

def populate_hourly():
    hourly_detections['cat'] += 1
    hourly_detections['dog'] += 2
    hourly_detections['mouse'] += 3

def populate_daily():
    daily_detections += hourly_detections

def run():
    populate_hourly()
    populate_daily()

    print(hourly_detections)
    print(daily_detections)

if __name__ == '__main__':
    run()

This code throws the following error within the populate_daily function: UnboundLocalError: local variable 'daily_detections' referenced before assignment

However, if we add the global flag specifically for daily_detections in the populate_daily function, the code runs flawlessly:

from collections import Counter

hourly_detections = Counter()
daily_detections = Counter()

def populate_hourly():
    hourly_detections['cat'] += 1
    hourly_detections['dog'] += 2
    hourly_detections['mouse'] += 3

def populate_daily():
    global daily_detections
    daily_detections += hourly_detections

def run():
    populate_hourly()
    populate_daily()

    print(hourly_detections)
    print(daily_detections)

if __name__ == '__main__':
    run()

The output is:

Counter({'mouse': 3, 'dog': 2, 'cat': 1})

Counter({'mouse': 3, 'dog': 2, 'cat': 1})

Can anyone explain this behavior and how best to avoid it?


Solution

  • don't forget to use global daily_detections and global hourly_detections at each function.

    Python thinks these are local variables unless you declare them as globals at the beginning of the function, and then after you are trying to do hourly_detections['cat'] += 1 you are basically trying to add one to "a non initialized variable"

    You may also send them if you want as function parameters as it is considered better practice (please read here).