Here is a comprehensive, Python interview questions, designed to be informative for both job seekers and interviewers.
Top 50 Python Interview Questions and Answers

Python continues to dominate the programming landscape, ranking as one of the most in-demand languages for web development, data science, artificial intelligence, and automation. Whether you are a fresh graduate or an experienced developer preparing for a career move, mastering common Python interview questions is essential to landing your dream job.
This comprehensive guide covers 50 essential Python interview questions, ranging from beginner-level syntax to advanced concepts like decorators, multithreading, and the Global Interpreter Lock (GIL). We have categorized these questions to help you prepare for roles such as Python Developer, Data Engineer, or Software Engineer.
Table of Contents
- Basic Python Interview Questions
- Intermediate Python Questions
- Advanced Python Questions
- Object-Oriented Programming (OOP)
- Python Libraries and Frameworks
- Tips to Ace the Python Interview
1. Basic Python Interview Questions
These questions test your foundational knowledge of Python syntax and core concepts.
1. Is Python a compiled or interpreted language?
Python is primarily an interpreted language. However, it is more accurate to say it uses an intermediate bytecode approach. When you run a Python script, the code is first compiled into bytecode (.pyc files), which is then interpreted by the Python Virtual Machine (PVM). This makes Python platform-independent but slower than purely compiled languages like C or C++.
2. What is the difference between a list and a tuple?
This is one of the most frequently asked Python interview questions.
- Mutability: Lists are mutable (can be changed), while tuples are immutable (cannot be changed after creation).
- Syntax: Lists use square brackets
[1, 2, 3]; tuples use parentheses(1, 2, 3). - Performance: Tuples are faster than lists because they have a fixed size.
- Use Case: Use lists for homogeneous data (e.g., list of names) and tuples for heterogeneous data (e.g., database record:
(id, name, age)).
3. How is memory managed in Python?
Python memory management is handled automatically by the Private Heap Space. All Python objects and data structures are stored in this private heap. The programmer does not have access to this heap; instead, the Python memory manager handles the allocation. The built-in garbage collector recycles unused memory to free up space, primarily using reference counting and cycle-detection algorithms.
4. Explain the use of the self parameter in Python classes.
The self parameter is a reference to the current instance of the class. It is used to access variables and methods that belong to the class. It does not have to be named self; you can name it anything you want, but it must be the first parameter of any function in the class.
class Car:
def __init__(self, brand):
self.brand = brand # 'self' refers to the instance
def show_brand(self):
print(self.brand)
5. What are Python decorators?
A decorator is a function that takes another function as an argument and extends its behavior without explicitly modifying it. It is a powerful tool for wrapping code. You often see decorators used in frameworks like Flask or Django.
def my_decorator(func):
def wrapper():
print("Something is happening before the function.")
func()
print("Something is happening after the function.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
6. What is the difference between deepcopy and shallow copy?
- Shallow Copy: Constructs a new compound object and then inserts references into it to the objects found in the original. It copies one level deep.
- Deep Copy: Constructs a new compound object and then recursively inserts copies of the objects found in the original. It copies all levels.
Usecopy.copy()for shallow copy andcopy.deepcopy()for deep copy.
7. Explain the map(), filter(), and reduce() functions.
map(): Applies a given function to all items in an input list and returns a map object (an iterator).map(function, iterable)filter(): Constructs an iterator from elements of an iterable for which a function returns true.filter(function, iterable)reduce(): Applies a rolling computation to sequential pairs of values in a list (must be imported fromfunctools).reduce(function, iterable)
2. Intermediate Python Questions
These questions assess your understanding of how Python works under the hood and your ability to write efficient code.
8. What is the Global Interpreter Lock (GIL)?
The Global Interpreter Lock (GIL) is a mutex that protects access to Python objects, preventing multiple threads from executing Python bytecode simultaneously in a single process. This means that even on multi-core systems, only one thread can execute Python code at a time. This simplifies memory management (making it thread-safe) but creates a bottleneck for CPU-bound multi-threaded programs. For I/O-bound tasks, threading is still useful as the lock is released during I/O operations.
9. How do you manage exceptions in Python?
Exception handling is done using the try, except, else, and finally blocks.
try: Block of code to be attempted.except: Block of code executed if an error occurs in the try block.else: Block executed if no exceptions occur.finally: Block that is always executed, regardless of whether an exception occurred (used for cleanup).
10. What are *args and **kwargs?
*args(Non-Keyword Arguments): Used to pass a variable number of non-keyword arguments to a function. It receives the arguments as a tuple.**kwargs(Keyword Arguments): Used to pass a variable number of keyword arguments to a function. It receives the arguments as a dictionary.
11. Explain list comprehension. Give an example.
List comprehension provides a concise way to create lists based on existing iterables. It consists of brackets containing an expression followed by a for clause, and optionally if clauses.
Syntax: [expression for item in iterable if condition]
# Traditional way
squares = []
for x in range(5):
squares.append(x**2)
# List comprehension
squares = [x**2 for x in range(5)] # Output: [0, 1, 4, 9, 16]
12. What is a generator and how does it differ from a list?
A generator is a function that produces a sequence of results using the yield keyword instead of return.
- Memory: Generators do not store all the values in memory; they generate them on the fly. Lists store all values in memory.
- Performance: Generators are slower than lists for iteration but are far more memory-efficient for large datasets.
- Iteration: Generators can only be iterated over once.
13. What is the difference between .py and .pyc files?
- .py: These are the source code files you write.
- .pyc: These are compiled bytecode files. When you import a module, Python creates a
.pycfile (inside the__pycache__folder) to speed up execution the next time the file is loaded.
14. How do you reverse a string in Python?
Python strings are immutable, so you cannot reverse them in place. The most common method is slicing.
my_string = "Python"
reversed_string = my_string[::-1] # Output: 'nohtyP'
15. What is pickling and unpickling?
The pickle module implements binary protocols for serializing and de-serializing a Python object structure.
- Pickling: The process of converting a Python object into a byte stream (for saving to a file or database).
- Unpickling: The inverse process, where a byte stream is converted back into a Python object.
3. Advanced Python Questions
For senior roles, interviewers will dig deep into architecture, internals, and performance.
16. What are metaclasses in Python?
A metaclass is the class of a class. Just as a class defines how an instance behaves, a metaclass defines how a class behaves. In Python, type is the built-in metaclass. Metaclasses are used to create APIs or tools that need to automatically alter class behavior (like Django ORM or SQLAlchemy). This is considered an advanced concept and a “hack” that should be used sparingly.
17. Explain the difference between __new__ and __init__.
__new__: This is the first step in instance creation. It is a static method that creates and returns a new object instance. It is used primarily for immutable subclasses and metaclasses.__init__: This is called after the instance has been created (__new__). It initializes the instance attributes. It does not return anything.
18. How does garbage collection work in Python?
Python’s garbage collector (GC) is enabled by default and runs automatically. It primarily uses two strategies:
- Reference Counting: Every object in Python keeps track of how many references point to it. When this count drops to zero, the memory is deallocated immediately.
- Generational Garbage Collection: To detect reference cycles (where objects reference each other but have no external references), Python has a cycle detector. Objects are grouped into three “generations” based on how many GC sweeps they have survived.
19. What is monkey patching? Is it a good practice?
Monkey patching refers to the dynamic modification of a class or module at runtime.
class MyClass:
def speak(self):
print("Hello")
def new_speak(self):
print("World")
# Monkey patch
MyClass.speak = new_speak
Pros: Quick fixes or adding features to third-party libraries.
Cons: Can lead to code that is hard to debug and maintain (“action at a distance”). It is generally considered a bad practice in production code unless absolutely necessary.
20. What is the difference between async and await in Python?
Introduced in Python 3.5, async and await are used for asynchronous programming.
async def: Defines a native coroutine (an asynchronous function). It returns a coroutine object.await: Is used inside anasyncfunction to suspend the execution of the coroutine until the awaited awaitable completes, allowing other tasks to run in the meantime.
This allows for concurrency, particularly useful for I/O-bound tasks, without the overhead of threads.
21. Explain the with statement in Python.
The with statement is used to wrap the execution of a block with methods defined by a context manager. It simplifies exception handling by encapsulating common preparation and cleanup tasks (like opening and closing files).
# Instead of this:
file = open('file.txt', 'r')
content = file.read()
file.close()
# Do this:
with open('file.txt', 'r') as file:
content = file.read()
# File is automatically closed after the block, even if an error occurs.
4. Object-Oriented Programming (OOP) in Python
Python is an object-oriented language, and these questions test your design skills.
22. What are the four pillars of OOP? How does Python implement them?
- Encapsulation: Bundling data and methods within a class. In Python, this is achieved using class attributes. “Private” members are denoted by a leading underscore
_or double underscore__(name mangling). - Abstraction: Hiding complex implementation details and showing only essential features. Achieved via abstract base classes (ABC module) and interfaces.
- Inheritance: A class (child) can derive properties and behaviors from another class (parent). Python supports multiple inheritance.
- Polymorphism: The ability to present the same interface for different data types (e.g.,
len()works for strings, lists, and dicts). Achieved through duck typing and method overriding.
23. What is method overloading and overriding?
- Method Overloading: Defining multiple methods with the same name but different parameters. Python does not support method overloading natively. If you define multiple methods with the same name, the last one overrides the previous ones. You can simulate it using default arguments or
*args. - Method Overriding: A child class provides a specific implementation of a method that is already defined in its parent class.
24. What is the diamond problem in multiple inheritance? How does Python resolve it?
The diamond problem occurs when a class inherits from two classes that have a common ancestor, leading to ambiguity about which ancestor’s method to call.
Python resolves this using the Method Resolution Order (MRO) . It follows the C3 linearization algorithm. You can view the MRO of a class by calling ClassName.__mro__ or ClassName.mro(). It follows a depth-first, left-to-right rule.
25. Explain the difference between classmethod and staticmethod.
@classmethod: Takes the class as the first argument (cls). It can modify class state that applies across all instances of the class.@staticmethod: Does not takeselforclsas an argument. It behaves like a plain function but belongs to the class’s namespace.
class MyClass:
@classmethod
def class_method(cls):
print(f"Called class method of {cls}")
@staticmethod
def static_method():
print("Called static method")
5. Python Libraries and Frameworks
Depending on the job role, you may be asked specific questions about popular libraries.
26. What is NumPy and how is it better than lists?
NumPy (Numerical Python) is a library for numerical computing. Its core feature is the ndarray (N-dimensional array), which is:
- Faster: Homogeneous arrays allow for vectorized operations and are stored in contiguous memory, making them faster than Python lists.
- More Functional: Provides a vast library of mathematical functions (linear algebra, Fourier transform, random number generation).
27. Explain the Pandas library and its core data structures.
Pandas is a library for data manipulation and analysis. It is built on top of NumPy.
- Series: A one-dimensional labeled array capable of holding any data type.
- DataFrame: A two-dimensional labeled data structure with columns of potentially different types. It is the most commonly used Pandas object, akin to a spreadsheet or SQL table.
28. What is the difference between Django and Flask?
- Flask: A “micro-framework.” It is lightweight, modular, and gives developers the freedom to decide which components (like database libraries or form validation) to use. It is best for small projects, microservices, and APIs.
- Django: A “batteries-included” framework. It comes with an ORM, admin panel, authentication, and many other features out of the box. It follows the “Don’t Repeat Yourself” (DRY) principle and is ideal for large, data-driven web applications.
29. What is an ORM? Why is it used?
ORM stands for Object-Relational Mapping. It is a programming technique that allows you to interact with a relational database (like SQL) using the object-oriented paradigm of your programming language (Python). Instead of writing raw SQL queries, you work with Python objects.
Example (Django ORM): User.objects.filter(first_name="John")
Benefits: Database abstraction (switch DBs easily), security (prevents SQL injection), and faster development.
30. How do you handle concurrency in Python?
Depending on the task:
- Threading: For I/O-bound tasks (network requests, file I/O). Limited by the GIL.
- Multiprocessing: For CPU-bound tasks (heavy computations). Bypasses the GIL by using separate processes with separate memory spaces.
- Asyncio: For high-level structured network code. Uses an event loop and coroutines (
async/await).
6. Coding and Problem-Solving Questions
These questions test your ability to write syntactically correct and efficient Python code on the spot.
31. Write a function to check if a string is a palindrome.
def is_palindrome(s):
s = s.lower().replace(" ", "") # Normalize: ignore case and spaces
return s == s[::-1]
# Test
print(is_palindrome("A man a plan a canal Panama")) # Output: True
32. Write a one-liner to find all the even numbers in a list.
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
evens = [num for num in numbers if num % 2 == 0]
print(evens) # Output: [2, 4, 6, 8]
33. How do you merge two dictionaries in Python 3.9+?
Python 3.9 introduced the union operator (|) for dictionaries.
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
merged_dict = dict1 | dict2
print(merged_dict) # Output: {'a': 1, 'b': 2, 'c': 3, 'd': 4}
34. Write a lambda function to sort a list of tuples by the second element.
data = [(1, 5), (3, 2), (7, 8)]
data.sort(key=lambda x: x[1]) # Sort by the second element
print(data) # Output: [(3, 2), (1, 5), (7, 8)]
35. Implement a Fibonacci sequence generator using a generator.
def fibonacci(limit):
a, b = 0, 1
while a < limit:
yield a
a, b = b, a + b
for num in fibonacci(10):
print(num) # Output: 0, 1, 1, 2, 3, 5, 8
36. What will be the output of print(type([1,2,3])) and print(type((1,2,3)))?
print(type([1,2,3]))-><class 'list'>print(type((1,2,3)))-><class 'tuple'>
37. How do you remove duplicates from a list?
The most efficient way is to convert it to a set and then back to a list. However, this does not preserve order.
my_list = [1, 2, 2, 3, 4, 4, 5]
unique_list = list(set(my_list))
print(unique_list) # Output: [1, 2, 3, 4, 5] (order may vary)
# To preserve order (Python 3.7+):
unique_ordered = list(dict.fromkeys(my_list))
38. Explain the difference between is and ==.
==: Compares the value of two objects (checks for equality).is: Compares the identity of two objects (checks if they are the same object in memory).
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True (values are the same)
print(a is b) # False (different objects in memory)
39. What is the output of print(0.1 + 0.2 == 0.3)?
The output is False. This is due to floating-point precision errors inherent in binary representation of decimal fractions. You should use math.isclose(0.1+0.2, 0.3) to compare floats.
40. Write a context manager using the contextlib module.
from contextlib import contextmanager
@contextmanager
def open_file(name, mode):
f = open(name, mode)
try:
yield f
finally:
f.close()
with open_file('test.txt', 'w') as f:
f.write('Hello, Context Manager!')
41. Explain the use of enumerate() in Python.
enumerate() adds a counter to an iterable and returns it as an enumerate object. It is useful for obtaining an indexed list.
my_list = ['apple', 'banana', 'cherry']
for index, value in enumerate(my_list):
print(f"Index: {index}, Value: {value}")
42. What is the difference between del, remove(), and pop() on lists?
remove(): Removes the first occurrence of a value by its value. (e.g.,list.remove('apple')).pop(): Removes an element by its index and returns it. If no index is provided, it removes and returns the last item.del: A statement that removes an item by its index or can delete the entire list/slice. It does not return the value.
43. How do you create a virtual environment in Python?
Using the venv module (built-in):
python -m venv myenv
To activate it:
- Windows:
myenv\Scripts\activate - macOS/Linux:
source myenv/bin/activate
44. What is the Walrus Operator?
The walrus operator := (introduced in Python 3.8) allows you to assign a value to a variable as part of an expression.
# Without walrus
data = input("Enter data: ")
while data != "quit":
print(f"You entered: {data}")
data = input("Enter data: ")
# With walrus
while (data := input("Enter data: ")) != "quit":
print(f"You entered: {data}")
45. Explain the functools.lru_cache decorator.
lru_cache is a decorator that wraps a function with a Least Recently Used (LRU) cache. It saves time when a function is called repeatedly with the same arguments by storing the results.
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
46. How do you handle multiple exceptions in one line?
You can catch multiple exceptions by providing a tuple of exception types.
try:
# some code
except (TypeError, ValueError, IndexError) as e:
print(f"An error occurred: {e}")
47. What is a frozenset?
A frozenset is an immutable version of a Python set. Once created, elements cannot be added or removed from it. It is hashable and can be used as a key in a dictionary.
48. Write a function to count the frequency of characters in a string.
from collections import Counter
def char_frequency(s):
return Counter(s)
# Or manually:
def char_frequency_manual(s):
freq = {}
for char in s:
freq[char] = freq.get(char, 0) + 1
return freq
49. Explain __slots__ in Python.
__slots__ is a class variable that restricts the attributes an instance can have. It prevents the creation of a __dict__ per instance, saving memory, especially when creating many instances of a class.
class Point:
__slots__ = ['x', 'y'] # Only 'x' and 'y' are allowed
def __init__(self, x, y):
self.x = x
self.y = y
50. How would you profile a Python script for performance?
- Built-in: Use the
cProfilemodule.python -m cProfile my_script.py - Line-by-line: Use the
line_profilerpackage. - Time measurement: Use
time.perf_counter()for small code blocks.
7. Tips to Ace the Python Interview
- Write Clean Code: Use meaningful variable names. Follow PEP 8 guidelines.
- Explain as You Go: Interviewers want to see your thought process. Talk through the problem before you start coding.
- Consider Edge Cases: Always think about what happens with empty inputs, negative numbers, or large datasets.
- Know Your Tools: Be comfortable with using Python’s built-in functions (
map,filter,zip,enumerate,any,all). - Practice on Whiteboards: If it’s a physical interview, practice writing code by hand to get used to the lack of an IDE’s auto-completion.
By preparing with these 50 Python interview questions, you will be well-equipped to demonstrate your knowledge, from basic syntax to complex internals. Good luck