Top 50 Python Interview Questions with Answers (2026): Fresher to Python Expert

Python has become the dominant language for data science, machine learning, backend development, and coding interviews. Its clean syntax and massive standard library allow developers to implement complex algorithms in half the code of C++ or Java — but interviewers still expect you to deeply understand how Python works under the hood.
This guide covers all 50 interview questions across Python's memory fundamentals (pass-by-object-reference, mutable vs immutable, shallow vs deep copy, generators, garbage collection), the entire collections module (defaultdict, Counter, deque, NamedTuple), data structure implementation in Python (linked lists, stacks, monotonic stack, binary trees, heaps via heapq, graphs), and advanced algorithmic paradigms (BFS/DFS, Dijkstra, Union-Find, DP, memoization, @functools.cache, sliding window, backtracking, and Pythonic tricks).
Every answer includes a “💡 Why Interviewers Ask This” insight so you know exactly what is being tested — not just what the answer is.
Contents
- 1.Python Memory & Core Fundamentals (Q1–Q10)
Pointers vs References · Pass-by-Object-Reference · Mutable vs Immutable · List internals · == vs is · Shallow vs Deep Copy · Generators · append() vs insert(0) · List comprehension · Garbage Collection
- 2.The collections Module & Hash Maps (Q11–Q16)
dict internals · Hash Collision · defaultdict · Counter · deque · NamedTuple
- 3.Linked Lists, Stacks & Queues (Q17–Q21)
ListNode · Reverse LL · Stack with list · Monotonic Stack · Floyd's Cycle Detection
- 4.Trees & Heaps (Q22–Q29)
TreeNode · BST · Level-Order BFS · DFS traversals · Trie · Heap · heapq · Max-Heap trick
- 5.Graphs & Algorithms (Q30–Q35)
Adjacency List · DFS · BFS · Dijkstra · Union-Find · Topological Sort
- 6.Algorithmic Paradigms & Pythonic Tricks (Q36–Q50)
DP · Memoization · @functools.cache · Sliding Window · Two Pointers · Backtracking · Sort dict · XOR trick · Reverse · any/all · enumerate · zip · len() O(1) · GIL · Python vs C++
- 7.Common Interview MistakesMutable defaults · GIL misconceptions · Shallow vs deep copy · Pass-by-object-reference
- 8.Expert Interview StrategyPythonic idioms · Time complexity · Decorators · Virtual environments
- 9.Real-World Job ApplicationsBackend Developer · Data Engineer · DevOps / Automation Engineer
Python Memory & Core Fundamentals Interview Questions (Q1–Q10)
Are there explicit Pointers in Python?
Python does not have explicit, C-style pointers. Instead, variables act as References (or labels) pointing to objects stored in the memory heap. You can check the memory address of an object using the built-in id() function, but you cannot perform arithmetic on these addresses.
Is Python Pass-by-Value or Pass-by-Reference?
Python uses Pass-by-Object-Reference (sometimes called Pass-by-Assignment). If you pass a mutable object (like a list or dict) to a function, modifying it in place alters the original object. If you reassign the variable name inside the function, the outer scope is unaffected — you've only rebound the local name.
my_list = []), the outer scope won't see the change. You must mutate it in place (my_list.clear()).What is the difference between Mutable and Immutable data types?
- Mutable: The object's internal state can be changed after creation — e.g.,
list,dict,set. - Immutable: The object's state cannot be changed. Any “modification” creates a completely new object in memory — e.g.,
int,float,str,tuple.
What is a Python list internally?
Despite the name, a Python list is not a Linked List. It is implemented in CPython as a Dynamic Array of pointers. The array holds references to the actual objects stored elsewhere in memory.
arr[5] is O(1), but inserting at the beginning arr.insert(0, val) is an expensive O(n) — every pointer must shift right. What is the difference between == and is?
==: Checks for Value Equality — do these two objects contain the same data?is: Checks for Identity / Memory Equality — do these two variables point to the exact same physical object in memory?
is None, not == None.What is the difference between a Shallow Copy and a Deep Copy?
- Shallow Copy (
list.copy()): Creates a new list object, but inserts references to the same child objects. Modifying a nested list affects both copies. - Deep Copy (
copy.deepcopy()): Creates a new object and recursively creates actual copies of all nested objects. Fully independent.
path array to your results, modifying path later will corrupt your saved results. You need path[:] or path.copy(), or a list literal.What is an Iterator vs a Generator?
- Iterator: An object that implements
__iter__()and__next__(), storing its full state in memory. - Generator: A special type of iterator created using a function with the
yieldkeyword. It lazily generates values one at a time, using virtually zero memory.
What is the Time Complexity of list.append() vs list.insert(0, val)?
append(): O(1) amortized — adds to the end of the dynamic array.insert(0, val): O(n) — every single element in the dynamic array must be shifted one space to the right in memory.
pop(0) or insert(0, val) in a while loop will destroy your algorithm's performance. Use collections.deque instead.What is List Comprehension?
List Comprehension is a concise, highly optimized syntactic construct for creating a new list based on the values of an existing iterable.
squares = [x**2 for x in range(10) if x % 2 == 0]for loop with .append().How does Garbage Collection work in Python?
Python uses two mechanisms: Reference Counting (when an object's reference count drops to 0, it is immediately freed) combined with a Generational Garbage Collector to detect and clean up cyclic references (e.g., Node A points to Node B, and Node B points back to Node A).
The collections Module & Hash Maps Interview Questions (Q11–Q16)
How does a dict work under the hood?
A Python dictionary is implemented as a Hash Table. It hashes the key to compute an index into a sparse array of slots. As of Python 3.7+, dictionaries officially maintain their insertion order. Search, insertion, and deletion are all O(1) on average.
What is a Hash Collision?
A Hash Collision occurs when two different keys generate the exact same hash value. Python resolves this using Open Addressing with random probing — searching for the next available empty slot in the memory array.
What is collections.defaultdict?
A defaultdict is a subclass of the standard dictionary. If you access or modify a key that does not exist, it automatically creates the key and assigns it a default value (e.g., 0 for int, or [] for list), preventing KeyError exceptions.
adj = defaultdict(list). What is collections.Counter?
Counter is a specialized dictionary designed for counting hashable objects. It instantly creates a frequency map.
from collections import Counter
freq = Counter("abracadabra") # {'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1} What is collections.deque?
A deque (Double-Ended Queue) is implemented in Python as a doubly linked list of fixed-size blocks. It provides blazing-fast O(1) appends and pops from both ends: append, appendleft, pop, popleft.
pop(0) is O(n). What is a NamedTuple?
A NamedTuple is a subclass of tuples that allows you to access elements by name (like an object property) instead of just an integer index, while maintaining the immutability and memory efficiency of a standard tuple.
point.x is much cleaner than point[0].Linked Lists, Stacks & Queues Interview Questions (Q17–Q21)
How do you represent a Linked List Node in Python?
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = nextHow do you optimally reverse a Linked List in Python?
Python allows multiple assignment, meaning you can update all three pointers in a single elegant line without needing a temporary variable.
curr.next, prev, curr = prev, curr, curr.nextHow do you implement a Stack in Python?
Use a standard Python list. Because lists are dynamic arrays, adding to the end (append()) and removing from the end (pop()) are both O(1) operations, perfectly simulating LIFO behavior.
stack = []
stack.append(1) # push → O(1)
val = stack.pop() # pop → O(1)Stack class, no import.What is a Monotonic Stack?
A Monotonic Stack is a stack whose elements are kept in strictly increasing or strictly decreasing order. When a new element breaks the order, elements are popped until the invariant is satisfied again. The algorithm processes each element at most twice — once pushed, once popped — giving O(n) overall.
How do you detect a cycle in a Linked List?
Use Floyd's Tortoise and Hare Algorithm. Create a slow pointer (moves 1 step) and a fast pointer (moves 2 steps). If slow == fast at any point, a cycle exists. If fast reaches None, no cycle exists. Time complexity: O(n). Space: O(1).
visited = set() costs O(n) memory. You must know the O(1) space solution.Trees & Heaps Interview Questions (Q22–Q29)
How do you represent a Binary Tree Node in Python?
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = rightWhat is a Binary Search Tree (BST)?
A BST is a binary tree where the left child's value is always less than the parent's, and the right child's value is always greater. This structure guarantees O(log n) search, insert, and delete on a balanced tree.
How do you perform a Level-Order Traversal (BFS) on a tree?
Import deque from collections. Append the root to the deque. While the deque is not empty, popleft() the current node, process it, and append its left and right children.
from collections import deque
def level_order(root):
if not root:
return []
queue, result = deque([root]), []
while queue:
node = queue.popleft()
result.append(node.val)
if node.left: queue.append(node.left)
if node.right: queue.append(node.right)
return resultHow do you traverse a tree using DFS?
DFS is implemented recursively using the Python call stack:
- Inorder (Left → Root → Right): Returns BST nodes in sorted order.
- Preorder (Root → Left → Right): Used for copying a tree.
- Postorder (Left → Right → Root): Used for deleting a tree from the bottom up.
What is a Trie (Prefix Tree)?
A Trie is a tree where each node represents a character. A Python Trie node typically contains a boolean is_end_of_word and a dictionary children = mapping characters to child nodes. Insert and search run in O(L) where L is the word length.
What is a Heap?
A Heap is a specialized complete binary tree implemented as a flat array. It supports O(1) access to the min (or max) element, with insertions and deletions in O(log n) time.
How does the heapq module work in Python?
The heapq module provides functions to use a standard Python list as a heap. By default, heapq only implements a Min-Heap.
import heapq
h = [3, 1, 4, 1, 5]
heapq.heapify(h) # O(n) → transforms list in-place
heapq.heappush(h, 2) # O(log n) → insert
smallest = heapq.heappop(h) # O(log n) → remove & return minHeap class. You must know how to use the heapq utility functions on a plain list.How do you implement a Max-Heap in Python?
Because heapq only supports Min-Heaps, the standard Pythonic trick is to negate all values before pushing, and negate again when popping.
import heapq
max_heap = []
heapq.heappush(max_heap, -5) # negate before push
heapq.heappush(max_heap, -1)
heapq.heappush(max_heap, -8)
largest = -heapq.heappop(max_heap) # negate on pop → 8Graphs & Algorithms Interview Questions (Q30–Q35)
How is a Graph typically represented in Python?
Using an Adjacency List built with defaultdict(list) — O(V + E) space, far more memory-efficient than a 2D matrix for sparse graphs.
from collections import defaultdict
adj = defaultdict(list)
adj['A'].append('B')
adj['A'].append('C')How do you perform Depth-First Search (DFS) in a Graph?
Create a visited = set() to track seen nodes and prevent infinite loops. Use a recursive helper to visit a node, add it to visited, and recursively call DFS on all unvisited neighbors.
def dfs(node, adj, visited):
visited.add(node)
for neighbor in adj[node]:
if neighbor not in visited:
dfs(neighbor, adj, visited)
visited = set()
dfs('A', adj, visited)How do you perform Breadth-First Search (BFS) in a Graph?
Create a visited = set() and a queue = deque([start_node]). Add start_node to visited. While the queue is not empty, popleft() the node, process it, and enqueue all unvisited neighbors.
from collections import deque
def bfs(start, adj):
visited = {start}
queue = deque([start])
while queue:
node = queue.popleft()
for neighbor in adj[node]:
if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)How do you implement Dijkstra's Algorithm in Python?
Dijkstra's uses a Min-Heap (heapq) storing (distance, node) tuples. Initialize all distances to infinity, set the source to 0, and push it. Repeatedly pop the minimum-distance node, and relax its edges.
import heapq
def dijkstra(graph, src):
dist = {node: float('inf') for node in graph}
dist[src] = 0
heap = [(0, src)] # (distance, node)
while heap:
d, u = heapq.heappop(heap)
if d > dist[u]:
continue # stale entry
for v, w in graph[u]:
if dist[u] + w < dist[v]:
dist[v] = dist[u] + w
heapq.heappush(heap, (dist[v], v))
return distTime complexity: O((V + E) log V)
What is a Disjoint Set (Union-Find)?
Union-Find is a data structure using a parent dictionary to track elements partitioned into disjoint subsets. It uses find() with path compression and union() by rank to merge sets in near O(1) amortized time.
What is Topological Sorting?
A Topological Sort is a linear ordering of vertices in a Directed Acyclic Graph (DAG). If there is an edge U → V, node U must appear before node V in the output. It can be implemented via DFS (add to result on finish) or Kahn's Algorithm (BFS with in-degree tracking).
Algorithmic Paradigms & Pythonic Tricks Interview Questions (Q36–Q50)
What is Dynamic Programming (DP)?
DP breaks a complex problem down into simpler, overlapping subproblems. It stores the results in a data structure (dict or array) to avoid calculating the exact same recursive state twice. This converts exponential O(2ⁿ) naive recursion into polynomial O(n) solutions.
What is Memoization in Python?
Memoization is the “Top-Down” implementation of DP. You pass a dictionary memo = {} into a recursive function. Before computing, check if state in memo; if so, return the cached value instantly.
def fib(n, memo={}):
if n <= 1:
return n
if n in memo:
return memo[n]
memo[n] = fib(n-1, memo) + fib(n-2, memo)
return memo[n] What is the @functools.cache decorator?
Python 3.9+ includes @functools.cache (and @functools.lru_cache). Placing this decorator above a recursive function causes Python to automatically memoize inputs and outputs, eliminating the need to write a manual memo dictionary.
from functools import cache
@cache
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)@cache saves 5 minutes of typing and proves you are an expert in modern Python standard libraries.What is the Sliding Window Technique?
Sliding Window creates a “window” using two pointers (left and right) over a list or string. Expand the right boundary to process new elements, and shrink the left boundary when a constraint is violated. Achieves O(n) instead of O(n²).
What is the Two-Pointer Technique?
Two-Pointers uses two indices (usually left = 0 and right = len(arr) - 1) traversing an array simultaneously. Used on sorted arrays to find pairs that sum to a target in O(n) instead of O(n²).
How do you implement Backtracking?
Backtracking follows the pattern: Choose → Explore → Undo. Append a choice to the path, recurse, then path.pop() to undo and try the next option.
def backtrack(path, remaining):
if not remaining:
results.append(path[:]) # snapshot
return
for choice in remaining:
path.append(choice) # Choose
backtrack(path, ...) # Explore
path.pop() # UndoHow do you sort a dictionary by its values in Python?
# Sort by value, descending
sorted_dict = dict(sorted(my_dict.items(), key=lambda x: x[1], reverse=True))What is the XOR trick for finding a missing number?
Leverage the bitwise XOR operator (^). Because X ^ X = 0, XORing all numbers in the array with all numbers 1–N will cancel out duplicates, leaving only the missing number. Runs in O(n) time, O(1) space.
# Find the missing number in [0..n]
def missing(nums):
xor = len(nums)
for i, v in enumerate(nums):
xor ^= i ^ v
return xorWhat is the fastest way to reverse a string or list in Python?
Use Python's slicing syntax with a negative step:
reversed_string = my_string[::-1]
reversed_list = my_list[::-1]for loop to reverse a string in Python is considered amateur. What are the any() and all() functions?
any(iterable): ReturnsTrueif at least one element evaluates toTrue.all(iterable): ReturnsTrueonly if every element evaluates toTrue.
any([False, False, True]) # True
all([True, True, False]) # False What is Python's enumerate() function?
enumerate() adds an automated counter to an iterable, allowing you to get both the index and the value simultaneously without managing a manual i += 1 counter.
for index, val in enumerate(my_list):
print(index, val)range(len(arr)) is frowned upon when you need the value alongside the index. What does the zip() function do?
zip() takes two or more iterables and aggregates them into tuples, pairing elements at the same index together.
a = [1, 2, 3]
b = ['x', 'y', 'z']
list(zip(a, b)) # [(1, 'x'), (2, 'y'), (3, 'z')] What is the time complexity of len(list) or len(string)?
Exactly O(1). Python objects store their length as an internal C-struct property. It does not iterate through the array to count elements.
len() inside a for loop condition does not negatively impact performance.What is the Global Interpreter Lock (GIL)?
The GIL is a mutex in CPython that allows only one thread to execute Python bytecode at a time, even on multi-core processors. Standard Python multithreading is therefore ineffective for CPU-bound DSA tasks. To achieve true parallelism, use the multiprocessing module.
Why use Python for DSA if C++ and Java are mathematically faster?
While Python's interpreter makes raw execution slower, its clean syntax, built-in dynamic arrays, and massive standard library (collections, itertools, heapq) allow developers to write complex algorithms in half the time and lines of code compared to C++ or Java. Developer time is often more expensive than CPU time.
Common Mistakes in Python Interviews
- Confusing mutable default arguments: Using a mutable object like
def func(lst=[])causes the default to persist across calls. Always useNoneas default and create the list inside the function — interviewers test this constantly. - Saying "lists and tuples are the same except mutability": While mutability is the key difference, tuples are also hashable (usable as dict keys), have slightly faster iteration, and signal intent of fixed data. A shallow answer misses these nuances.
- Not understanding the GIL: Claiming Python supports true multi-threading for CPU-bound tasks is wrong. The Global Interpreter Lock means only one thread executes Python bytecode at a time. Use
multiprocessingfor CPU parallelism. - Mixing up shallow and deep copy:
copy()creates a new object but references the same nested objects.deepcopy()recursively copies everything. Failing to explain this distinction signals weak understanding of Python's object model. - Forgetting that Python is pass-by-object-reference:It's neither pass-by-value nor pass-by-reference. Mutable objects can be modified in-place inside functions; immutable objects cannot. Saying "pass by reference" is technically incorrect.
- Ignoring generators when asked about memory efficiency: When processing large datasets, using list comprehensions loads everything into memory. Generators (
yield) produce items lazily. Not mentioning generators for large-data questions is a missed opportunity.
Expert Interview Strategy for Python Roles
- Show Pythonic idioms, not just correct code. Use list comprehensions, f-strings, context managers, and unpacking. Writing
for i in range(len(lst))instead offor item in lstsignals a non-Pythonic mindset. - Mention time complexity unprompted. When discussing built-in data structures, state that dict lookup is O(1) average, list append is O(1) amortized, and list insert at index 0 is O(n). This shows you think about performance.
- Connect decorators to real use cases. Don't just define decorators abstractly — mention
@login_requiredin Django,@cachefrom functools, and@retrypatterns. Concrete examples demonstrate production experience. - Know the difference between Python 2 and 3. Even though Python 2 is EOL, interviewers ask about
printas function vs statement, integer division, Unicode handling, andrangevsxrange. A quick comparison shows breadth. - Discuss virtual environments and dependency management. Mention
venv,pip freeze,requirements.txt, and modern tools likepoetryoruv. This signals you can manage real Python projects, not just write scripts.
How These Concepts Apply in Real Python Jobs
Backend Developer
Uses decorators for middleware, context managers for DB connections, generators for streaming responses, and async/await for high-concurrency APIs. Django/Flask/FastAPI frameworks rely on these core Python concepts daily.
Data Engineer
Relies on list/dict comprehensions for data transformation, generators for processing large files without memory overflow, and multiprocessing for parallel ETL pipelines. Understanding the GIL is critical for pipeline performance.
DevOps / Automation Engineer
Writes Python scripts for infrastructure automation, uses exception handling for resilient tooling, leverages subprocess and os modules for system tasks, and builds CLI tools with argparse or click.
Topics covered in this guide
Topics in this guide: Python memory model, pass-by-object-reference, mutable vs immutable, list internals, == vs is, shallow vs deep copy, generators, collections module (defaultdict, Counter, deque, NamedTuple), linked lists, stacks, queues, trees, heaps (heapq), graphs, BFS/DFS, Dijkstra, Union-Find, dynamic programming, memoization, @functools.cache, sliding window, backtracking, and Pythonic tricks.
For freshers: Python variables as references, mutable vs immutable types, list operations (append vs insert), string and tuple properties, basic dictionary lookups, and Pythonic list comprehension.
For experienced professionals: CPython memory internals, hash collision resolution (open addressing), Global Interpreter Lock (GIL) implications for concurrency, generator state persistence, advanced data structures implementation, and recursion optimization using @functools.cache.
Interview preparation tips: Practice writing clean, idiomatic Python code, avoid mutable default arguments, master the collections and heapq modules, and be ready to explain the time complexity of built-in functions.
Conclusion: Master Python Interviews
These 50 Python interview questions cover the essential concepts you'll encounter in backend developer, data engineer, automation engineer, and full-stack Python roles. Mastering these topics demonstrates a solid understanding of Python fundamentals, OOP principles, data structures, memory management, and modern Python best practices.
The key to interview success is not just knowing the syntax, but understanding the "why" behind each concept. Each answer includes insights into what interviewers are testing — from core language mechanics to practical problem-solving skills.
After reviewing these answers, reinforce your learning with hands-on practice and review the theory notes. The combination of conceptual understanding + practical coding + theory review creates the strongest foundation for Python interviews.
Frequently Asked Questions
Q.Are there explicit Pointers in Python?
Q.Is Python Pass-by-Value or Pass-by-Reference?
Q.What is the difference between Mutable and Immutable types in Python?
Q.What is a Python list internally?
Q.How does collections.deque differ from a Python list for queue operations?
Found these questions helpful? Share them with your peers.
Common Interview Mistakes
Errors that eliminate candidates
- Giving textbook definitions without showing a concrete Python use case.
- Skipping trade-offs and answering as if there is only one correct engineering decision.
- Over-answering for 2-3 minutes without structure, metrics, or outcomes.
Expert Interview Strategy
30-second answer rule
- Start with a one-line definition, then explain one real scenario from Python.
- Use a 3-step structure: concept, practical example, and interviewer intent.
- Close with one trade-off (performance, scale, security, or maintainability).
Real-World Job Applications
These Python patterns are directly tested for production roles where interviewers expect clear debugging steps, architecture trade-offs, and communication under time pressure.
Conclusion
Mastering these Python interview questions means explaining concepts quickly, connecting them to real systems, and justifying decisions with practical trade-offs.
Frequently Asked Questions
How should I prepare this topic in 7 days? Focus on high-frequency patterns, rehearse 30-second answers, and revise one practical example per category.
What do interviewers score most? Clarity, structured thinking, and your ability to reason through constraints and trade-offs.