100 Most Frequently Asked Python Interview Questions & Answers
π 1. Python Fundamentals
1. What is Python?
Python is a high-level, interpreted, dynamically typed, general-purpose programming language known for its readability and extensive ecosystem.
Key characteristics:
- Dynamically typed
- Garbage collected
- Object-oriented
- Supports functional and procedural programming
- Extensive standard library
- Cross-platform
- Large third-party ecosystem
Python is widely used for web development, automation, data engineering, AI/ML, scripting, and DevOps.
2. What are the main features of Python?
The most important features are:
- Simple and readable syntax
- Dynamic typing
- Automatic memory management
- Object-oriented programming
- First-class functions
- Exception handling
- Modules and packages
- Generators and iterators
- Extensive libraries
- Cross-platform support
3. Is Python compiled or interpreted?
The common answer is both, depending on what level you mean.
Typically:
Python source code
β
Bytecode
β
Python Virtual Machine
For CPython, .py source code is compiled into bytecode, which is then executed by the Python virtual machine.
So saying simply βPython is interpretedβ is an oversimplification.
4. What is CPython?
CPython is the reference and most widely used implementation of Python.
It is written primarily in C and includes:
- Python parser
- Bytecode compiler
- Python Virtual Machine
- Memory management
- Garbage collection
Other implementations include PyPy, Jython, and IronPython.
5. What is PEP 8?
PEP 8 is Pythonβs official style guide.
It defines conventions for:
- Naming
- Indentation
- Imports
- Line length
- Whitespace
- Code organization
Example:
def calculate_total(price, tax):
return price + price * tax
PEP 8 improves consistency and readability.
6. What is the difference between Python 2 and Python 3?
Python 2 reached end of life in 2020.
Important Python 3 improvements include:
print()is a function- Unicode strings by default
- Better exception syntax
- Improved type hints
- Async/await
- Dataclasses
- Pattern matching
- Many standard-library improvements
Modern development should use Python 3.
7. What are Pythonβs built-in data types?
Common built-in types include:
NoneType
bool
int
float
complex
str
list
tuple
set
frozenset
dict
bytes
bytearray
Example:
name = "Bill" # str
age = 55 # int
price = 10.5 # float
skills = ["Java", "Python"] # list
8. What is dynamic typing?
Python determines the type of an object at runtime.
x = 10
x = "hello"
x = [1, 2, 3]
The variable name x can refer to objects of different types.
Python is therefore dynamically typed.
9. What is duck typing?
Duck typing means that Python cares about an objectβs behavior, rather than its explicit type.
βIf it walks like a duck and quacks like a duck, treat it as a duck.β
Example:
def save(obj):
obj.write("hello")
The function doesnβt require a particular class. Any object implementing write() can work.
10. What does None mean?
None represents the absence of a value.
Python
Run
result = None
It is an instance of NoneType.
Use:
if result is None:
...
rather than:
if result == None:
...
π¦ 2. Lists, Tuples, Sets & Dictionaries
11. What is the difference between a list and a tuple?
A list is mutable while a tuple is immutable.
numbers = [1, 2, 3]
numbers[0] = 10
Works.
numbers = (1, 2, 3)
numbers[0] = 10
Raises an exception.
Use tuples for fixed collections and lists for collections that need modification.
12. Why are tuples generally faster than lists?
Tuples are immutable, so Python can optimize their representation.
For example:
Python
Run
items = (1, 2, 3)
usually requires less overhead than:
Python
Run
items = [1, 2, 3]
The difference matters mostly for large numbers of objects or performance-sensitive code.
13. What is a set?
A set is an unordered collection of unique elements.
numbers = {1, 2, 3, 3}
print(numbers)
Result:
{1, 2, 3}
Sets are especially useful for fast membership testing:
if user_id in user_ids:
...
Average lookup complexity is approximately O(1).
14. What is a dictionary?
A dictionary stores key-value pairs.
user = {
"name": "Bill",
"age": 55
}
Access:
Python
Run
user["name"]
Modern Python dictionaries preserve insertion order.
15. Why must dictionary keys be hashable?
Dictionary keys use hashing for efficient lookup.
Therefore keys must have a stable hash value.
Valid:
{
"name": "Bill",
123: "value",
(1, 2): "value"
}
Invalid:
{
[1, 2]: "value"
}
because lists are mutable and unhashable.
16. What is the difference between set and frozenset?
set is mutable:
s = {1, 2}
s.add(3)
frozenset is immutable:
Python
Run
s = frozenset([1, 2])
A frozenset can itself be used as a dictionary key or as an element of another set.
17. How do you remove duplicates from a list?
Simple approach:
Python
Run
unique = list(set(numbers))
But this does not preserve order.
To preserve order:
Python
Run
unique = list(dict.fromkeys(numbers))
Example:
numbers = [1, 2, 2, 3, 1]
unique = list(dict.fromkeys(numbers))
Result:
[1, 2, 3]
18. What is list slicing?
Slicing extracts part of a sequence.
numbers = [0, 1, 2, 3, 4]
numbers[1:4]
Result:
[1, 2, 3]
Syntax:
Python
Run
sequence[start:stop:step]
19. What does [::-1] do?
It reverses a sequence.
text = "Python"
print(text[::-1])
Result:
nohtyP
20. What is a list comprehension?
A concise way to construct a list.
Traditional:
squares = []
for x in range(10):
squares.append(x * x)
List comprehension:
Python
Run
squares = [x * x for x in range(10)]
You can add conditions:
Python
Run
even = [x for x in numbers if x % 2 == 0]
π§ 3. Python Memory & Object Model
21. How does Python manage memory?
CPython manages memory using:
- Private heap
- Reference counting
- Garbage collector
- Memory allocators
Python programmers normally donβt manually allocate or free objects.
22. What is reference counting?
CPython tracks how many references point to an object.
a = []
b = a
The list now has multiple references.
When its reference count reaches zero, CPython can normally reclaim it immediately.
23. What is garbage collection?
Reference counting cannot handle all circular references.
Example:
a = []
b = []
a.append(b)
b.append(a)
The objects reference each other.
Pythonβs cyclic garbage collector detects and cleans up unreachable cycles.
24. What is the difference between is and ==?
== compares values.
is compares object identity.
a = [1, 2]
b = [1, 2]
a == b # True
a is b # False
Use is primarily for singleton checks:
if value is None:
...
25. What is object identity?
Every Python object has an identity.
You can inspect it with:
Python
Run
id(obj)
Two variables can reference the same object:
a = []
b = a
a is b
Result:
True
26. What is mutable vs immutable?
Mutable objects can be changed after creation.
Examples:
list
dict
set
Immutable objects cannot.
Examples:
int
float
str
tuple
frozenset
27. Are tuples completely immutable?
The tuple itself is immutable, but it can contain mutable objects.
t = ([1, 2], 3)
t[0].append(4)
This is allowed.
The tuple still references the same list object.
28. What is shallow copy?
A shallow copy creates a new outer object but doesnβt recursively copy nested objects.
import copy
b = copy.copy(a)
Nested references may still point to the same objects.
29. What is deep copy?
Deep copy recursively copies nested objects.
Python
Run
b = copy.deepcopy(a)
Changes to nested objects in b wonβt affect a.
30. What is the difference between assignment and copying?
This is an important interview question.
a = [1, 2]
b = a
No copy occurs.
Both variables reference the same list.
Python
Run
b = a.copy()
creates a shallow copy.
βοΈ 4. Functions
31. What are *args and **kwargs?
*args collects positional arguments.
def add(*args):
return sum(args)
**kwargs collects keyword arguments.
def show(**kwargs):
print(kwargs)
Example:
Python
Run
show(name="Bill", age=55)
32. What are default arguments?
Example:
def greet(name="Guest"):
return f"Hello {name}"
If no argument is supplied:
Python
Run
greet()
returns:
Hello Guest
33. Why are mutable default arguments dangerous?
Consider:
def add_item(item, items=[]):
items.append(item)
return items
The same list is reused across calls.
Better:
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items
This is a very common interview trap.
34. Are functions first-class objects in Python?
Yes.
Functions can be:
- Assigned to variables
- Passed as arguments
- Returned from functions
- Stored in collections
Example:
def greet():
return "Hello"
func = greet
print(func())
35. What is a lambda function?
A lambda is a small anonymous function.
Python
Run
square = lambda x: x * x
Equivalent to:
def square(x):
return x * x
Lambdas are commonly used with functions such as sorted().
36. What is a higher-order function?
A function that accepts another function or returns one.
Example:
def apply(func, value):
return func(value)
Usage:
Python
Run
apply(lambda x: x * 2, 10)
37. What is a closure?
A closure is a function that remembers variables from its enclosing scope.
def multiplier(n):
def multiply(x):
return x * n
return multiply
double = multiplier(2)
print(double(5))
Result:
10
38. What is LEGB?
Python resolves names using:
L β Local
E β Enclosing
G β Global
B β Built-in
Example:
x = "global"
def outer():
x = "enclosing"
def inner():
print(x)
inner()
inner() finds the enclosing x.
39. What are global and nonlocal?
global modifies a global variable.
count = 0
def increment():
global count
count += 1
nonlocal modifies a variable in an enclosing function.
def counter():
count = 0
def increment():
nonlocal count
count += 1
return increment
40. What is recursion?
Recursion occurs when a function calls itself.
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
Python has a recursion depth limit, so recursion isnβt always appropriate for large inputs.
π§© 5. Object-Oriented Python
41. What is a class?
A class defines the structure and behavior of objects.
class User:
def __init__(self, name):
self.name = name
Create an object:
Python
Run
user = User("Bill")
42. What is self?
self refers to the current object instance.
class User:
def __init__(self, name):
self.name = name
self.name stores data on that particular object.
43. What is __init__?
__init__ is an initializer called when an object is created.
Python
Run
user = User("Bill")
Python invokes:
Python
Run
__init__(...)
It initializes the objectβs state.
44. What is inheritance?
Inheritance allows one class to reuse or extend another class.
class Animal:
def speak(self):
print("sound")
class Dog(Animal):
pass
Dog inherits speak().
45. What is multiple inheritance?
A class can inherit from multiple classes.
class A:
pass
class B:
pass
class C(A, B):
pass
Python uses MRO to determine method resolution order.
46. What is MRO?
MRO stands for Method Resolution Order.
You can inspect it with:
Python
Run
C.mro()
Python uses the C3 linearization algorithm to determine the order.
47. What is polymorphism?
Polymorphism allows different objects to expose the same interface.
class Dog:
def speak(self):
return "Woof"
class Cat:
def speak(self):
return "Meow"
Both can be used through:
Python
Run
animal.speak()
48. What is encapsulation in Python?
Python doesnβt enforce traditional private fields like Java.
Instead, conventions are used:
Python
Run
_name
means βinternal/protected by convention.β
Name mangling:
Python
Run
__name
makes accidental access harder.
49. What is abstraction?
Abstraction exposes what an object does while hiding implementation details.
Python supports abstract classes through abc.
from abc import ABC, abstractmethod
class Payment(ABC):
@abstractmethod
def pay(self):
pass
50. What is a @property?
property allows methods to be accessed like attributes.
class User:
@property
def name(self):
return self._name
Usage:
Python
Run
user.name
instead of:
Python
Run
user.name()
π― 6. Decorators, Iterators & Generators
51. What is a decorator?
A decorator modifies or extends a function without changing its source code.
def log(func):
def wrapper(*args, **kwargs):
print("Calling function")
return func(*args, **kwargs)
return wrapper
Usage:
@log
def hello():
print("Hello")
52. Why use functools.wraps?
Without wraps, decorators can lose metadata such as:
__name__
__doc__
Better:
from functools import wraps
def log(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
53. What is an iterator?
An iterator implements:
__iter__()
__next__()
Example:
it = iter([1, 2, 3])
next(it)
Each call retrieves the next value.
54. What is an iterable?
An iterable is an object that can produce an iterator.
Examples:
list
tuple
str
dict
set
You can do:
for item in iterable:
...
55. What is a generator?
A generator produces values lazily using yield.
def numbers():
for i in range(10):
yield i
Values are generated only when requested.
56. Generator vs list?
List:
Python
Run
numbers = [x for x in range(1_000_000)]
stores all values in memory.
Generator:
Python
Run
numbers = (x for x in range(1_000_000))
generates values lazily.
Generators are useful for large datasets and streaming.
57. What does yield do?
yield pauses a generator and returns a value.
def count():
yield 1
yield 2
The function resumes from where it stopped when next() is called again.
58. What is a generator expression?
Similar to list comprehension but lazy.
Python
Run
squares = (x * x for x in range(10))
Compare:
Python
Run
[x * x for x in range(10)]
versus:
Python
Run
(x * x for x in range(10))
59. What is yield from?
It delegates iteration to another iterable or generator.
def numbers():
yield from range(5)
Itβs especially useful for composing generators.
60. What is the difference between iterator and generator?
A generator is a convenient way to create an iterator.
An iterator generally implements __iter__() and __next__() explicitly.
Generators automatically provide iterator behavior.
β‘ 7. Exceptions & Context Managers
61. How does exception handling work?
Python uses:
try:
...
except:
...
else:
...
finally:
...
Example:
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero")
62. What is the difference between except Exception and bare except?
Avoid:
except:
pass
because it catches things such as KeyboardInterrupt.
Prefer:
except Exception as e:
...
when appropriate.
63. How do you create a custom exception?
class PaymentError(Exception):
pass
Then:
Python
Run
raise PaymentError("Payment failed")
64. What is raise?
raise explicitly throws an exception.
if amount < 0:
raise ValueError("Amount cannot be negative")
65. What is finally?
finally executes regardless of whether an exception occurs.
try:
process()
finally:
cleanup()
Itβs commonly used for resource cleanup.
66. What is a context manager?
A context manager manages resources automatically.
Example:
with open("data.txt") as file:
content = file.read()
The file is automatically closed.
67. What are __enter__ and __exit__?
They implement the context-manager protocol.
class Resource:
def __enter__(self):
return self
def __exit__(self, exc_type, exc, tb):
...
68. How can you create a context manager without a class?
Using contextlib.contextmanager:
from contextlib import contextmanager
@contextmanager
def resource():
print("open")
yield
print("close")
Usage:
with resource():
print("working")
π 8. Concurrency & Parallelism
69. What is the GIL?
The Global Interpreter Lock in traditional CPython implementations historically allowed only one thread at a time to execute Python bytecode within a process.
This means threads arenβt generally a way to achieve CPU-bound parallelism in traditional CPython.
However, Pythonβs concurrency story has evolved, including support for free-threaded CPython builds in modern Python releases.
70. Threading vs multiprocessing?
Threading:
- Shared memory
- Lightweight
- Good for I/O-bound workloads
- Easier communication
Multiprocessing:
- Separate processes
- Separate memory
- Better for CPU-bound workloads
- Higher overhead
Example:
I/O-bound β threading / asyncio
CPU-bound β multiprocessing / suitable native extensions
71. What is asyncio?
asyncio provides asynchronous programming using an event loop.
Example:
import asyncio
async def hello():
await asyncio.sleep(1)
print("Hello")
asyncio.run(hello())
It is particularly useful for high-concurrency I/O workloads.
72. What are async and await?
async defines a coroutine:
async def fetch():
...
await suspends it while waiting for another awaitable:
Python
Run
result = await fetch()
This allows other tasks to run during I/O waits.
73. What is an event loop?
The event loop coordinates asynchronous tasks.
Conceptually:
Task A β waiting for network
β
Task B β running
β
Task C β waiting
β
Task A β network completed
This enables efficient concurrency without creating one OS thread per request.
74. What is a race condition?
A race condition occurs when program behavior depends on timing between concurrent operations.
Example:
Python
Run
counter += 1
Multiple threads/processes accessing shared state can produce incorrect results without proper synchronization.
75. How do you synchronize threads?
Python provides primitives such as:
threading.Lock
threading.RLock
threading.Semaphore
threading.Event
threading.Condition
Example:
with lock:
shared_counter += 1
π§ͺ 9. Testing & Code Quality
76. What testing frameworks are commonly used?
Common Python testing tools include:
pytestunittestunittest.mockhypothesis- coverage tools
pytest is particularly popular because of its concise syntax and powerful fixture system.
77. What is mocking?
Mocking replaces a dependency with a controlled test object.
Example:
from unittest.mock import Mock
payment_service = Mock()
payment_service.pay.return_value = True
This allows you to test application logic without calling the real service.
78. What is dependency injection?
Instead of creating dependencies inside a class:
class OrderService:
def __init__(self):
self.payment = PaymentService()
inject them:
class OrderService:
def __init__(self, payment):
self.payment = payment
This improves testability and flexibility.
79. What is TDD?
Test-Driven Development generally follows:
Red
β
Green
β
Refactor
- Write a failing test.
- Implement the minimum code.
- Make the test pass.
- Refactor.
80. What is the difference between unit and integration tests?
Unit test:
- Tests a small isolated component
- Usually mocks dependencies
- Fast
Integration test:
- Tests multiple components together
- Often uses real databases/services
- Slower but validates integration behavior
π 10. Python Web Development
81. What Python web frameworks are popular?
Major frameworks include:
- Django
- Flask
- FastAPI
- Pyramid
For modern API development, FastAPI is particularly popular because of type hints, validation, automatic OpenAPI documentation, and asynchronous support.
82. Django vs Flask?
Django is batteries-included:
ORM
Authentication
Admin
Routing
Middleware
Templates
Flask is lightweight and minimal.
Choose Django when you want a comprehensive framework and Flask when you want greater architectural freedom.
83. Why is FastAPI popular?
FastAPI provides:
- Type-hint-based validation
- Automatic OpenAPI documentation
- Async support
- High performance
- Pydantic-based data validation
Example:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{user_id}")
async def get_user(user_id: int):
return {"id": user_id}
84. What is WSGI?
WSGI β Web Server Gateway Interface β defines an interface between Python web applications and web servers.
It is traditionally associated with synchronous Python web applications.
85. What is ASGI?
ASGI β Asynchronous Server Gateway Interface extends the Python web server/application interface for asynchronous applications.
It supports use cases such as:
- Async HTTP
- WebSockets
- Long-lived connections
FastAPI commonly runs through an ASGI server such as Uvicorn.
ποΈ 11. Databases & APIs
86. How do you connect Python to a database?
Common libraries include:
psycopg
SQLAlchemy
mysqlclient
asyncpg
Example using SQLAlchemy:
from sqlalchemy import create_engine
engine = create_engine("postgresql://...")
87. What is an ORM?
ORM means Object-Relational Mapping.
It maps database records to programming-language objects.
SQLAlchemy is a major Python ORM/database toolkit.
Instead of writing:
SQL
SELECT * FROM users WHERE id = 10;
you can work with Python objects and expressions.
88. What is SQL injection?
SQL injection occurs when untrusted input is incorporated into SQL incorrectly.
Bad:
Python
Run
query = f"SELECT * FROM users WHERE name='{name}'"
Use parameterized queries or an ORM instead.
89. How do you call a REST API in Python?
A common approach is using requests:
import requests
response = requests.get("https://example.com/api/users")
response.raise_for_status()
data = response.json()
For asynchronous applications, an async HTTP client such as httpx can be appropriate.
90. How do you serialize Python objects to JSON?
Use the json module:
import json
data = {"name": "Bill"}
text = json.dumps(data)
obj = json.loads(text)
Frameworks such as FastAPI commonly provide higher-level serialization through their data-modeling stack.
π 12. Performance & Advanced Python
91. How do you improve Python performance?
Typical strategies:
- Choose better algorithms.
- Use appropriate data structures.
- Avoid unnecessary allocations.
- Use generators for streaming.
- Cache expensive operations.
- Profile before optimizing.
- Use asynchronous I/O for suitable workloads.
- Use multiprocessing for suitable CPU-bound workloads.
- Move computational hotspots to optimized native libraries when appropriate.
A common mistake is optimizing code without measuring it first.
92. What is Big O notation?
Big O describes how algorithm complexity grows with input size.
Examples:
List lookup O(n)
Dictionary lookup O(1) average
Binary search O(log n)
Sorting O(n log n)
Nested loop O(nΒ²)
Understanding algorithmic complexity is critical for Python coding interviews.
93. What is timeit?
timeit measures execution time for small pieces of Python code.
Example:
import timeit
result = timeit.timeit(
"sum(range(1000))",
number=10000
)
Itβs useful for micro-benchmarks.
94. What is profiling?
Profiling identifies where a program spends its time or memory.
Common tools include:
cProfile
profile
py-spy
tracemalloc
A good engineering approach is:
Measure β Identify bottleneck β Optimize β Measure again
95. What is caching?
Caching stores expensive results so they can be reused.
Python provides:
from functools import lru_cache
@lru_cache
def fibonacci(n):
...
Modern Python also provides functools.cache for an unbounded cache.
96. What is __slots__?
__slots__ can restrict which attributes instances have and can reduce per-instance memory overhead.
Example:
class User:
__slots__ = ("name", "age")
def __init__(self, name, age):
self.name = name
self.age = age
It can be useful when creating very large numbers of small objects.
97. What are type hints?
Type hints document expected types.
def add(a: int, b: int) -> int:
return a + b
Python generally does not enforce these annotations at runtime by itself.
Tools such as mypy, Pyright, and IDEs can use them for static analysis.
98. What are dataclasses?
Dataclasses reduce boilerplate for classes primarily representing data.
from dataclasses import dataclass
@dataclass
class User:
name: str
age: int
Python automatically generates methods such as __init__ and __repr__.
99. What is structural pattern matching?
Python introduced match / case pattern matching.
Example:
def handle(command):
match command:
case "start":
return "Starting"
case "stop":
return "Stopping"
case _:
return "Unknown"
It can also match more complex structures.
100. How is Python used in AI and modern software engineering?
Python has become one of the dominant languages for AI because of its ecosystem.
Common technologies include:
NumPy
Pandas
PyTorch
TensorFlow
scikit-learn
Transformers
FastAPI
Pydantic
LangChain
LlamaIndex
A modern AI application might look like:
βββββββββββββββββ
β Frontend β
βββββββββ¬ββββββββ
β
βββββββββΌββββββββ
β Python API β
β FastAPI β
βββββββββ¬ββββββββ
β
βββββββββββββββΌββββββββββββββ
β β β
βββββββΌββββββ βββββββΌββββββ ββββββΌβββββ
β PostgreSQLβ β Redis β β Vector β
β β β Cache β β Store β
βββββββββββββ βββββββββββββ βββββββββββ
β
βββββββββΌββββββββ
β LLM / AI β
β Model β
βββββββββββββββββ
For senior interviews, donβt stop at syntax. Be prepared to explain why you would choose a particular Python feature, framework, concurrency model, database strategy, or architecture.
π₯ 15 Python Questions That Separate Senior Engineers From Juniors
If youβre interviewing for a Senior Python / Backend / AI Engineer position, I would especially prepare these:
| # | Question | What Interviewer Is Testing |
|---|---|---|
| 1 | How does the GIL work? | Runtime knowledge |
| 2 | Threading vs multiprocessing vs asyncio? | Concurrency |
| 3 | How does Python manage memory? | CPython internals |
| 4 | Shallow vs deep copy? | Object model |
| 5 | Why are mutable default arguments dangerous? | Python semantics |
| 6 | Explain closures and decorators. | Functional Python |
| 7 | Iterator vs iterable vs generator? | Python internals |
| 8 | How does asyncio work? | Async architecture |
| 9 | How would you optimize a slow Python service? | Engineering judgment |
| 10 | How would you design a scalable FastAPI service? | System design |
| 11 | How do you test external dependencies? | Testing |
| 12 | How do you prevent SQL injection? | Security |
| 13 | How do you diagnose a memory leak? | Production debugging |
| 14 | How would you process a 100 GB file? | Streaming/data engineering |
| 15 | How would you build a production AI API in Python? | Modern architecture |
π‘ The key interview strategy
For junior interviews, interviewers often ask:
βWhat does this Python feature do?β
For senior interviews, expect:
βWhy would you use it, what are its trade-offs, and what happens under load?β
For example, donβt just know:
async def fetch():
...
Be ready to explain:
asyncio
β
Event Loop
β
Coroutine
β
await
β
Non-blocking I/O
β
Other tasks execute
And be able to explain when asyncio is the wrong choice.
That distinction is often what separates someone who knows Python syntax from someone who can design production systems with Python.