#1 India's Top IT Training Institute

×

About Uncodemy

Know more about who we are and what we stand for.

About Us

About Us

Discover our mission to equip individuals with essential IT skills and industry expertise.

Read More →
UnCodeMy Gallery

UnCodeMy Gallery

Explore highlights from our IT training sessions and success stories.

Read More →
×

Free Resources

Learn, practice and plan your career — bilkul free.

Tutorials

Tutorials

Step-by-step written tutorials to learn any technology at your own pace.

Read More →
Free Counselling

Free Counselling

Book a free video counselling session and pick the right course for you.

Read More →
Online Compiler

Online Compiler

Write, run and test your code online — no setup required.

Read More →

Interview Insights · Python

The Python Question That Ninety Percent of Candidates Fumble

It sounds like a beginner question: 'Is Python pass by value or pass by reference?' Yet it trips up a huge share of candidates, including experienced ones. The fumble is not a missing fact. It is a missing mental model.

Tracks
The Fumble · Live Interactive
Answer
—
What the candidate says
Test
—
The code I show next
Outcome
—
Does the answer survive
Question→Label→Test code→Model
Click an answer to see whether it survives the two small code examples that interviewers use to test it.

Home / Tutorials / Career Guides / The Python Question That Ninety Percent of Candidates Fumble

Interview Insights · Python

The Python Question That Ninety Percent of Candidates Fumble

CALLERCALLMUTATEREBINDitemsName in callerPoints to a listStartBind paramlst -> same listNo copy madeSharedlst.append()Changes objectCaller sees itVisiblelst = [...]New objectCaller unawareLocal
Python binds the parameter name to the same object the caller passed. Mutating that object is visible outside; rebinding the name is not.

Quick summary — Pass by assignment

Python is neither pass by value nor pass by reference in the classic sense; it passes object references by assignment. Candidates fumble this question because they try to pick one of two labels borrowed from other languages. Whichever label they choose, the interviewer can show a small piece of code where it gives the wrong prediction. The fix is a mental model, not a label: a function parameter is a new name bound to the same object the caller passed. Mutating that object is visible outside. Rebinding the name is not. This page explains the model, the code that tests it and the mutable default follow-up.

In this guide you will learn:

  1. Why both common labels fail when tested with real code
  2. The names-and-objects model that predicts every case
  3. Mutation versus rebinding, with examples you can run
  4. The mutable default argument follow-up, and its fix
  5. How to phrase the answer in under a minute

SECTION 01The question, and why most answers fall apart

I ask: 'If I pass a list into a function and the function changes it, does the caller see the change?' Many candidates say 'Python is pass by reference, so yes'. Then I show them a function that does lst = lst + [4] and ask what the caller sees. They predict the change is visible. It is not.

Other candidates say 'Python is pass by value', which fails the first test immediately, because append inside a function does change the caller's list. Each label works for one example and breaks on the other. That is the fumble: picking a label from C or Java instead of describing what Python actually does.

Answer givenPredicts append correctly?Predicts reassignment correctly?Verdict
Pass by valueNo, says caller is unchangedYesBreaks on mutation
Pass by referenceYesNo, says caller sees the new listBreaks on rebinding
Depends on mutable or immutablePartlyPartlyClose, but mixes two separate ideas
Pass by assignment (object reference)YesYesSurvives both tests
def add_item(lst):
    lst.append(4)

items = [1, 2, 3]
add_item(items)
print(items)   # [1, 2, 3, 4]  - caller sees the change

# 'Pass by value' predicts [1, 2, 3]. Wrong.
two_tests.py

Two short functions, and each label fails one of them. When I see a candidate predict both correctly and explain why, I know they understand Python's object model, which affects how they will write and debug almost every function.

Key insight: The question is not asking for a label. It is asking whether you can predict what happens. Answer with the model, then show the two cases.

SECTION 02The model that predicts every case: names and objects

In Python, every value is an object, and variables are names attached to objects. When you call a function, Python attaches the parameter name to the same object the caller passed. Nothing is copied. From then on, two things can happen inside the function.

Mutation: you change the object itself, with append, update, item assignment or += on a list. Both names still point to that object, so the caller sees the change. Rebinding: you attach the local name to a different object, with plain =. The caller's name still points to the original object, so nothing changes outside. Immutable objects like ints, strings and tuples simply have no mutation methods, so only rebinding is possible.

Operation inside functionTypeCaller sees change?Why
lst.append(x)MutationYesChanges the shared list object
lst += [x]Mutation (for lists)YesList += extends in place, then rebinds to the same object
lst = lst + [x]RebindingNo+ creates a new list; only the local name moves
n += 1 (int)RebindingNoints are immutable, so a new int object is created
def show(lst):
    print("param id:", id(lst))
    lst.append("m")          # mutation
    print("after append:", id(lst))
    lst = ["new"]            # rebinding
    print("after rebind:", id(lst))

data = ["a"]
print("caller id:", id(data))
show(data)
print(data)   # ['a', 'm']

# caller id and param id are the same number.
# after append: still the same.
# after rebind: a different number.
# The caller only sees what happened BEFORE the rebind.
names_and_objects.py

The += example is a favourite follow-up because it looks like a contradiction. It is not. For lists, += calls __iadd__, which extends the list in place. Tuples have no in-place version, so Python falls back to creating a new tuple and rebinding. The model still predicts both: ask whether the object changed or the name moved.

Remember: Ask one question for every line inside the function: did this change the object, or move the name? That single question answers every variant of this interview question.

SECTION 03The follow-up: mutable default arguments

If you answer the first question well, expect this next: 'What is wrong with def add(item, bucket=[])?' It is the same model applied to defaults. A default value is created once, when the function is defined, not each time it is called. If the default is a mutable list and the function mutates it, every call that uses the default shares the same list.

Candidates who fumbled the first question usually fumble this one too. Candidates who understood the first one can often work out this answer even if they have never seen it, which is exactly what I hope to watch.

CodeWhat candidates expectWhat actually happensFix
def add(x, bucket=[])A fresh list each callOne list shared across callsUse bucket=None, then create a list inside
def log(msg, when=datetime.now())Current time each callTime fixed at definitionDefault to None and call now() inside
def f(cfg={})Empty dict each callOne dict, changes persistcfg=None, then cfg = {} if cfg is None
def f(n=0)Fresh 0 each callFine: ints are immutableNo fix needed
def add_tag(tag, tags=[]):
    tags.append(tag)
    return tags

print(add_tag("python"))   # ['python']
print(add_tag("java"))     # ['python', 'java']   - surprise!
print(add_tag("sql"))      # ['python', 'java', 'sql']

print(add_tag.__defaults__)
# (['python', 'java', 'sql'],)  - the default itself has grown
mutable_default.py

Printing __defaults__ is a nice touch in an interview. It shows the default list sitting on the function object and growing, which proves the explanation rather than just stating it. In Uncodemy Python sessions, we use this exact demonstration because students remember it far better than the rule.

Pro move: Connect the two questions yourself: 'This is the same idea as passing a list: the function holds a reference to one list object, and mutating it is visible everywhere that object is used.'
How Uncodemy helps: At Uncodemy, the Python Training Course in Noida builds this into the batch: you practise Python interview questions in live mock interviews with trainers, get feedback on every answer, and work on real projects you can explain with confidence.

SECTION 04Practise the answer until it is automatic

Use these three sheets to make the model second nature. The goal is a calm one-minute answer, followed by confident predictions for any variation the interviewer shows you.

THE ONE-MINUTE ANSWER (say it aloud daily)

"Python passes arguments by assignment. The parameter
becomes a new name for the same object the caller
passed. No copy is made.

If the function mutates that object, like append on a
list, the caller sees the change. If the function
rebinds the name with =, only the local name moves,
and the caller is unaffected.

Immutable objects like ints and strings cannot be
mutated, so for them it behaves like pass by value."

Then offer: "I can show both cases in code."
pass_by_assignment_practice.md

SECTION 05Habits that make this question easy

These habits turn a commonly fumbled question into one of your strongest moments.

  • Drop the labels — Do not start with 'pass by value' or 'pass by reference'. Start with names and objects, then mention the labels only to compare.
  • Always show two cases — One mutation example and one rebinding example together prove your model in a way a definition never can.
  • Use id() to prove it — Printing ids before and after a change is a quick, convincing demonstration in any live round.
  • Copy defensively when needed — If a function must not change its input, say you would copy it first. It shows you think about the caller.
  • Know the default-argument fix — None as a sentinel is the standard pattern. Be ready to write it from memory.
Pro tip: Ask an Uncodemy trainer or a friend to write five tiny variations of the pass-by-assignment example. Predict each before running. Once you get all five right twice in a row, this question is yours.

SECTION 06Interview Q&A — Pass by assignment

Q1Is Python pass by value or pass by reference?

Neither in the classic sense. Python passes by assignment: the function parameter becomes a new name bound to the same object the caller passed. Mutating that object is visible to the caller. Rebinding the parameter with = only affects the local name.

Q2Why does appending to a list inside a function change the original?

Because the parameter and the caller's variable both refer to the same list object. append changes that object in place, so the change is visible through every name that refers to it.

Q3How can a function avoid modifying the list it receives?

Make a copy at the start, for example lst = list(lst) or lst.copy(), and work on that. For nested data, copy.deepcopy may be needed. Alternatively, return a new list instead of changing the input.

Q4What is the problem with mutable default arguments?

Default values are evaluated once, when the function is defined. A mutable default such as a list is shared by every call that uses it, so changes accumulate between calls. The standard fix is to default to None and create a new list inside the function.

Q5Why does += change a list in the caller but not a tuple?

For lists, += calls __iadd__, which extends the list in place, so the shared object changes. Tuples are immutable and have no in-place add, so += creates a new tuple and rebinds the local name, leaving the caller's tuple unchanged.

SECTION 07Test yourself — Pass by assignment quiz

Five questions. No sign-up.

0 / 5

Pick an answer to see why it is right or wrong.

SECTION 08Frequently asked questions

Does Python pass arguments by reference?

Not exactly. Python passes object references by assignment. The function can change a mutable object it receives, but reassigning the parameter does not affect the caller's variable.

Why does my list change after calling a function in Python?

The function received a reference to the same list and changed it in place, for example with append, extend or item assignment. Copy the list first if the function should not affect the original.

What is a mutable default argument in Python?

It is a default parameter value like a list or dict. Because defaults are created once, a mutable default is shared between calls, and changes made in one call appear in later calls.

Are strings passed by value in Python?

Strings are passed the same way as everything else, by assignment. Because strings are immutable, a function cannot change the caller's string, so in practice it behaves like pass by value.

How do I explain pass by assignment in an interview?

Say that parameters are new names for the caller's objects, then show two tiny examples: append, which the caller sees, and reassignment, which the caller does not. Offer the mutable default as a related case.

How can I prepare for Python interview questions with a trainer?

Yes. Uncodemy's Python Training Course in Noida (classroom and online) includes live projects, one-to-one mock interviews and resume reviews, so you practise Python interview questions with trainer feedback before the real interview. You can book a free demo class from this page to see how the sessions work.

Classroom & online · Noida

Master the Python fundamentals interviews test

Our Python Training Course covers Python's object model, data structures, functions and real projects, with mock rounds on the questions candidates fumble most.

Talk to a counsellor for current fees
  • Python object model in depth
  • Prediction and tracing drills
  • Mock technical rounds
  • Weekday & weekend batches