解决Python中意外的UnboundLocalError问题——最大堆化函数报错排查
Hey there, let's break down why you're hitting this UnboundLocalError and fix it step by step.
The Root Cause: Name Conflict
The error happens because you're reusing the same name max_child_index for two different things:
- A global function
def max_child_index(parent_index, array): - A local variable inside
max_heapifythat you try to assign to
When Python processes the line:
max_child_index = max_child_index(index, array)
It immediately marks max_child_index as a local variable (since you're assigning a value to it in the function). So when it tries to run the right-hand side (max_child_index(index, array)), it looks for a local variable with that name—but that variable hasn't been assigned yet, hence the "referenced before assignment" error. Python ignores the global function with the same name here because it already categorized max_child_index as a local variable.
Fix 1: Rename the Local Variable
The simplest fix is to use a unique name for the local variable. Let's use max_child_idx instead:
def left_child(index): return (index * 2) + 1 def right_child(index): return (index + 1) * 2 def parent(index): return (index - 1) // 2 def max_child_index(parent_index, array): left = left_child(parent_index) right = right_child(parent_index) # Fix edge case: handle missing right child if right >= len(array): return left if array[left] >= array[right]: return left else: return right def max_heapify(array, index): swapped = True while swapped: swapped = False max_child_idx = max_child_index(index, array) # Stop if there are no valid children left if max_child_idx >= len(array): break if array[index] < array[max_child_idx]: array[index], array[max_child_idx] = array[max_child_idx], array[index] print(array) index = max_child_idx swapped = True
Fix 2: Patch the max_child_index Edge Case
Your original max_child_index function had a hidden bug: if a parent only has a left child (the right child is out of bounds), accessing array[right] would throw an IndexError. The updated code above adds a check for this scenario, returning the left child directly when the right child doesn't exist.
Test the Fixed Code
Run your test case again:
array = [1, 14, 9, 10, 2, 8, 3, 7, 4, 16] max_heapify(array, 0) assert array == [14, 10, 9, 7, 2, 8, 3, 1, 4, 16]
This will now execute without errors and pass the assertion.
Key Takeaway
Never reuse names for different entities (functions vs variables) in overlapping scopes—it breaks Python's variable resolution rules and leads to confusing bugs like this.
内容的提问来源于stack exchange,提问作者Lyxcoder

