Python Interview Questions: 25 Answers with Runnable Code
25 Python interview questions with short worked answers and runnable code: mutability, copies, scope, decorators, generators, OOP, errors and coding rounds.
Think of the driving test at the RTO in Indore. The inspector first asks a few questions: what does this sign mean, who has right of way at a roundabout. Then you drive a short route while they watch how you handle the car.
A Python interview has the same two parts: "signboard" questions, where you explain a concept, and a "short drive", a coding problem where the interviewer watches how you think. This page covers both.
Python interview questions are conceptual and coding questions that check whether a candidate understands how Python's objects, functions, classes and errors behave, and can apply that understanding to write correct, readable code under time pressure.
This is the final lesson of the series, after Python projects for beginners. Answers target Python 3.12+.
Python basics interview questions
1. Is Python compiled or interpreted?
Both. CPython first compiles source code into bytecode (the .pyc files in __pycache__), then its virtual machine interprets that bytecode. You never run a separate compile step, so Python is usually called interpreted.
2. What is the difference between a list, a tuple, a set and a dictionary?
| Type | Ordered | Mutable | Duplicates | Typical use |
|---|---|---|---|---|
list |
yes | yes | allowed | a sequence you change |
tuple |
yes | no | allowed | a fixed record, a dict key |
set |
no | yes | not allowed | uniqueness, membership tests |
dict |
insertion order | yes | keys unique | lookup by key |
3. What are mutable and immutable types?
A mutable object can change in place: lists, dicts and sets. An immutable one cannot: int, float, str, tuple and frozenset. "Changing" an immutable value really creates a new object.
name = "indore"
upper = name.upper()
print(name, upper)
scores = [70, 80]
alias = scores
alias.append(90)
print(scores)
try:
name[0] = "I"
except TypeError as err:
print("TypeError:", err)4. What is the difference between is and ==?
== compares values; is checks whether two names point to the same object in memory. Use is only for singletons such as None.
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b, a is b, a is c)
result = None
print(result is None)5. How are arguments passed to functions in Python?
By object reference, sometimes called "pass by assignment". The parameter becomes a new name for the same object. Mutating a mutable argument is visible to the caller; rebinding the parameter is not.
def add_item(cart, item):
cart.append(item)
def rename(label):
label = label + " (sold)"
cart, label = ["pen"], "notebook"
add_item(cart, "bag")
rename(label)
print(cart, label)6. Why is a mutable default argument dangerous?
Default values are evaluated once, when the function is defined. A list default is therefore shared by every call. Use None and create the list inside.
def add_order(item, orders=[]):
orders.append(item)
return orders
print(add_order("poha"))
print(add_order("jalebi"))
def add_order_safe(item, orders=None):
if orders is None:
orders = []
orders.append(item)
return orders
print(add_order_safe("poha"))
print(add_order_safe("jalebi"))7. What is the difference between a shallow copy and a deep copy?
A shallow copy creates a new outer container but reuses the inner objects. A deep copy duplicates everything, recursively. The difference only shows with nested data.
import copy
original = [["Indore", 1450], ["Bhopal", 980]]
shallow = copy.copy(original)
deep = copy.deepcopy(original)
original[0][1] = 9999
print("shallow sees:", shallow[0][1], "| deep sees:", deep[0][1])
print(shallow is original, shallow[0] is original[0], deep[0] is original[0])Names point to objects. Copies differ in how many levels of objects get duplicated.
Quick check
What does add_order("jalebi") return after add_order("poha") when the default is orders=[]?
The default list is created once and shared, so the second call appends to the same list.
Functions and scope interview questions
8. What are *args and **kwargs?
*args collects extra positional arguments into a tuple; **kwargs collects extra keyword arguments into a dict. At the call site, * and ** unpack a list or dict into arguments. The *args and **kwargs lesson has more.
def report(title, *values, **options):
print(title, values, options)
report("Sales", 10, 20, 30, currency="INR", rounded=True)
nums = [3, 1, 2]
settings = {"sep": " | "}
print(max(*nums), *nums, **settings)9. What is the LEGB rule?
It is the order Python searches for a name: Local, Enclosing function, Global (module), then Built-in. The first match wins. Assigning to a global or enclosing name needs global or nonlocal.
Lookup moves outward one ring at a time and stops at the first ring that has the name.
x = "global"
def outer():
x = "enclosing"
def inner():
print("inner sees:", x)
inner()
outer()
print("module sees:", x, "| built-in len:", len("abc"))10. What is a lambda function, and when should you use one?
A lambda is a small anonymous function written in one expression. Use it for short throwaway logic, most often as a key for sorting or in map. If it needs a name or several lines, use def.
orders = [("Indore", 1450), ("Bhopal", 980), ("Ujjain", 2300)]
print(sorted(orders, key=lambda o: o[1], reverse=True))
print(list(map(lambda o: o[0].upper(), orders)))
print(list(filter(lambda o: o[1] > 1000, orders)))
print(min(orders, key=lambda o: o[1])[0])11. What is a decorator?
A function that takes a function and returns a wrapped version, adding behaviour without editing it. @deco above def f means f = deco(f). See Python decorators.
from functools import wraps
def count_calls(func):
@wraps(func)
def wrapper(*args, **kwargs):
wrapper.calls += 1
return func(*args, **kwargs)
wrapper.calls = 0
return wrapper
@count_calls
def gst(amount):
return round(amount * 0.18, 2)
print(gst(1450), gst(980), "calls:", gst.calls, "name:", gst.__name__)12. What is the difference between a generator and a list comprehension?
A list comprehension builds every item in memory at once. A generator expression, or a function with yield, produces items one at a time on demand, so memory stays tiny. Python generators covers yield in depth.
import sys
as_list = [n * n for n in range(1_000_000)]
as_gen = (n * n for n in range(1_000_000))
print("generator is tiny:", sys.getsizeof(as_gen) < 500)
print("list is large:", sys.getsizeof(as_list) > 1_000_000)
print("same total:", sum(as_gen) == sum(as_list))
def countdown(n):
while n > 0:
yield n
n -= 1
print(list(countdown(3)))Python OOP interview questions
13. What do __init__ and self do, and what is the difference between __str__ and __repr__?
__init__ initialises a new object, and self is the object being set up. __str__ gives a friendly text for users (used by print); __repr__ gives an unambiguous developer view (used in lists and the console).
class Order:
def __init__(self, order_id, amount):
self.order_id = order_id
self.amount = amount
def __str__(self):
return f"Order {self.order_id}: Rs {self.amount}"
def __repr__(self):
return f"Order({self.order_id!r}, {self.amount!r})"
o = Order(1041, 1450)
print(o)
print([o])14. What is the difference between a classmethod and a staticmethod?
A @classmethod receives the class as cls and is used for alternative constructors. A @staticmethod receives nothing automatically; it is a plain function kept inside the class for organisation.
class Invoice:
GST = 0.18
def __init__(self, amount):
self.amount = amount
@classmethod
def from_text(cls, text):
return cls(int(text.replace("Rs", "").replace(",", "")))
@staticmethod
def is_valid(amount):
return amount > 0
inv = Invoice.from_text("Rs 1,450")
print(inv.amount, Invoice.is_valid(inv.amount), round(inv.amount * Invoice.GST, 2))15. How does multiple inheritance work in Python?
Python follows the method resolution order (MRO), computed with the C3 algorithm. It checks the class, then its parents left to right, and each class appears only once. ClassName.__mro__ shows the order.
class Base:
def who(self): return "Base"
class Card(Base):
def who(self): return "Card"
class Upi(Base):
def who(self): return "Upi"
class Wallet(Card, Upi):
pass
print(Wallet().who())
print([k.__name__ for k in Wallet.__mro__])16. What is duck typing?
Python cares whether an object has the method you call, not what class it belongs to: "if it quacks like a duck". Any object with a read() method can be passed where a file is expected, for example io.StringIO.
Errors, files and internals
17. In what order do try, except, else and finally run?
try runs first. except runs only on an error, else only when there was none, and finally always runs, even after return.
def parse(value):
try:
number = int(value)
except ValueError:
print(f"{value!r}: not a number")
return None
else:
print(f"{value!r}: parsed")
return number
finally:
print(" finally ran")
print(parse("1450"), parse("abc"))18. What does the with statement do?
It runs code inside a context manager, which sets something up and guarantees clean-up, even if an error occurs. Files close automatically. You can write your own with contextlib.contextmanager.
import os
import tempfile
from contextlib import contextmanager
@contextmanager
def step(name):
print("start", name)
try:
yield
finally:
print("end", name)
path = os.path.join(tempfile.mkdtemp(), "log.txt")
with step("write"), open(path, "w") as f:
f.write("order 1041 saved\n")
print("closed after with:", f.closed)19. What is the GIL, and how does Python manage memory?
The Global Interpreter Lock lets only one thread run Python bytecode at a time in CPython, so threads help with waiting (network, disk) but not with heavy calculation; use multiprocessing or numpy for that. Python 3.13 added an optional free-threaded build without the GIL. Memory is freed mainly by reference counting, with a garbage collector that cleans up reference cycles.
Python coding interview questions
Coding rounds favour short problems. Explain your approach and its time complexity before you type.
20. Check whether a string is a palindrome
Clean the text, then compare it with its reverse, s[::-1].
def is_palindrome(text):
clean = "".join(ch.lower() for ch in text if ch.isalnum())
return clean == clean[::-1]
for s in ["Malayalam", "Nitin", "Indore", "Was it a car or a cat I saw?"]:
print(f"{s!r}: {is_palindrome(s)}")21. Find two numbers that add up to a target
Store each number's index in a dictionary as you go, and look up target - n. This is O(n) instead of the O(n²) double loop.
def two_sum(nums, target):
seen = {}
for i, n in enumerate(nums):
if target - n in seen:
return seen[target - n], i
seen[n] = i
return None
print(two_sum([450, 1200, 980, 550], 1000))
print(two_sum([10, 20, 30], 100))22. Find the first non-repeating character
Count with Counter, then scan the string in order.
from collections import Counter
def first_unique(text):
counts = Counter(text)
for ch in text:
if counts[ch] == 1:
return ch
return None
print(first_unique("indoreindia"), first_unique("aabb"))
print(Counter("mississippi").most_common(2))23. Flatten a nested list
Recursion handles any depth: if an item is a list, flatten it too.
def flatten(items):
flat = []
for item in items:
if isinstance(item, list):
flat.extend(flatten(item))
else:
flat.append(item)
return flat
print(flatten([1, [2, 3], [4, [5, [6]]], 7]))24. Remove duplicates while keeping order
set() removes duplicates but loses order. dict.fromkeys keeps the first occurrence in order, because dictionaries preserve insertion order.
cities = ["Indore", "Bhopal", "Indore", "Ujjain", "Bhopal", "Dewas"]
print(list(dict.fromkeys(cities)))
print(sorted(set(cities)))
print(len(cities) - len(set(cities)), "duplicates removed")
seen, ordered = set(), []
for c in cities:
if c not in seen:
seen.add(c)
ordered.append(c)
print(ordered)25. What is the difference between loc and iloc in pandas?
loc selects by label (index names and column names, end included); iloc selects by integer position (end excluded, like Python slicing). Analyst interviews ask this constantly. More pandas and SQL questions are in data analyst interview questions.
import pandas as pd
df = pd.DataFrame({"city": ["Indore", "Bhopal", "Ujjain"], "sales": [1450, 980, 2300]},
index=["a", "b", "c"])
print(df.loc["a":"b", "sales"].tolist())
print(df.iloc[0:2, 1].tolist())
print(df.loc[df["sales"] > 1000, "city"].tolist())Quick check
Which pandas selector uses integer positions and excludes the end of a slice?
iloc is position-based like Python slicing; loc is label-based and includes the end label.
Common mistakes in Python interviews
- Answering with a definition only. Add a two-line example and one real use.
- Coding in silence. Explain the plan first; interviewers grade the reasoning.
- Forgetting edge cases. Mention empty input, duplicates and wrong types.
- Memorising without running. Predict and run every snippet above until none surprise you.
Key takeaways
- Know the mutability table and the
isvs==difference cold. - Explain copies, default arguments and argument passing with a tiny example each.
- Decorators, generators, LEGB and
*argsare the standard intermediate questions. - In OOP, cover
__init__,__str__vs__repr__, classmethod vs staticmethod and MRO. - In coding rounds, reach for dictionaries,
Counterand slicing, and state the complexity.
If you want mock interviews and feedback on your answers, Debugshala's interview-focused analytics training in Indore runs them as part of placement preparation. SQL rounds come next for most analyst roles: see SQL interview questions.
FAQ
What Python questions are asked in a fresher interview?
Fresher interviews usually cover data types and mutability, list vs tuple, is vs ==, loops and functions, *args and **kwargs, exception handling, basic OOP, and one or two short coding problems such as reversing a string or counting characters. Data roles add a few pandas questions such as loc vs iloc.
How should I prepare for a Python coding interview?
Revise the core concepts above, then solve two or three small problems daily with a timer, speaking your approach aloud. Focus on dictionaries, sets, strings and list slicing, which solve most fresher problems. Always test your solution with an empty input and an edge case before saying you are done.
Are Python interview questions different for data analyst roles?
The core Python questions are the same, but analyst interviews go lighter on algorithms and heavier on pandas: filtering, groupby, merging, handling missing values and date columns. Expect a SQL round as well. Practical questions such as cleaning a messy column are more common than tricky algorithm puzzles.
Where can I practise Python interview questions in Indore?
Run every answer on this page and change the inputs until you can predict each output. For timed practice, take mock Python interview MCQs on Debugshala Test. Debugshala's Old Palasia campus in Indore also offers placement assistance and a free demo class for its data analytics course.
From the team behind this site
Go further with the Data Analytics Course at Debugshala
These tutorials are written by Debugshala, a training and placement institute at Old Palasia, Indore. The classroom course adds live mentoring, real projects and interview preparation.
- Offline classes at Old Palasia, Indore
- Free demo class before you pay
- Non-IT, fresher and year-gap friendly
- Placement assistance
700+ students placed · 200+ hiring partners · 4.9★ Google rating