DEV Community

Cover image for What Happens When You Pass a List to a Python Function? Most Developers Get This Wrong.
Ameer Abdullah
Ameer Abdullah

Posted on

What Happens When You Pass a List to a Python Function? Most Developers Get This Wrong.

def double_items(lst):
    lst = [x * 2 for x in lst]
    return lst

original = [1, 2, 3]
result = double_items(original)
print(original)
print(result)
Enter fullscreen mode Exit fullscreen mode

What does original print?

If you said [1, 2, 3], you are right but possibly for the wrong reason.

If you said [2, 4, 6], you have the most common Python misconception about how function arguments work.


Python Is Neither Pass-by-Value Nor Pass-by-Reference

Every explanation I have seen frames this as Python being "pass-by-reference" for lists and "pass-by-value" for integers. This framing is wrong and it is why people keep getting confused.

Python is pass-by-object-reference. Or more precisely, names are bound to objects. Function arguments receive a reference to the same object the caller has. But what you do with that reference inside the function determines whether the original object changes.


Two Cases That Look Similar But Behave Differently

Case 1: Reassignment:

def modify(lst):
    lst = [x * 2 for x in lst]  # creates a NEW list, rebinds local name
    return lst

original = [1, 2, 3]
modify(original)
print(original)  # [1, 2, 3] — unchanged
Enter fullscreen mode Exit fullscreen mode

Inside modify, lst = [x * 2 ...] creates a brand new list and binds the local name lst to it. The original list is untouched. The local name lst now points to a different object than original.

Case 2: Mutation:

def modify(lst):
    for i in range(len(lst)):
        lst[i] = lst[i] * 2  # mutates the SAME list in place

original = [1, 2, 3]
modify(original)
print(original)  # [2, 4, 6] — changed
Enter fullscreen mode Exit fullscreen mode

Here lst[i] = ... modifies the list object that both lst and original point to. The original is changed because both names reference the same object.


The Mental Model That Makes This Clear

Think of it this way. A Python name is a label attached to an object. When you pass a list to a function, you are giving the function a copy of the label, not a copy of the object.

If the function attaches its label to a different object (reassignment), the original label still points to the original object.

If the function uses its label to modify the object itself (mutation), the original label still points to the same now-modified object.


Why This Matters in Interviews

Interviewers use this pattern to distinguish candidates who understand Python's object model from those who have only memorized surface-level behavior. The follow-up question is almost always "what would you change to make the function modify the original" or "how would you prevent the function from modifying the original."

Both answers require understanding the difference between reassignment and mutation.

For more problems testing this concept and others like it, try PyCodeIt, free.


Top comments (0)