Top 20 Python Interview Questions You Need to Ace Your Next Tech Interview (2025)

Are you ready to elevate your tech interview game? Mastering Python can be your golden ticket to landing that dream job in the software development industry. With its versatility, readability, and powerful libraries, Python has become a go-to language for many tech companies. However, acing an interview requires more than just coding skills; you need to be well-prepared to tackle common questions that employers often ask. In this article, we’ve compiled the top 20 Python interview questions you need to impress your potential employers and stand out from the competition. Whether you’re a seasoned developer or just starting your coding journey, these questions cover a range of topics that will help you showcase your Python expertise. Dive in and get ready to transform your interview preparation into a winning strategy!

These are fundamental. Expect one or more of these in most interviews. Below are representative questions, what they test, and strong answers with examples.

 

1. Is Python a compiled language or an interpreted language?

What the interviewer is checking: your understanding of how Python executes code, bytecode, and that different implementations behave differently.

Answer (concise): In CPython your source is compiled to bytecode (which may be stored as .pyc) and executed by the Python virtual machine. That makes it an interpreted language in practice, but compilation to bytecode still occurs. Other implementations (PyPy, JITs) may add additional compilation steps.

 

2. What is the difference between / and // in Python?

Short answer: / is true division (float result). // is floor division. Note negative numbers behave via floor semantics:

print(5 / 2)   # 2.5
print(5 // 2)  # 2
print(-5 // 2) # -3  (floor of -2.5)

 

3. What are some of the built-in data types in Python?

  • Text type: str

  • Numeric types: int, float, complex

  • Sequence types: list, tuple, range

  • Mapping: dict

  • Set types: set, frozenset

  • Boolean: bool

  • Binary types: bytes, bytearray, memoryview

Read more:
Data Types in Python

 

4. What’s the difference between a list and a tuple in Python?

  • A list is ordered, mutable, allows duplicates.

  • A tuple is ordered, immutable, allows duplicates.

  • Tuples can sometimes be slightly more efficient because of immutability (depending on implementation).

Key point: lists are mutable; tuples are immutable. Tuples can be used as dictionary keys if all elements are immutable.

 

5. Explain what *args and **kwargs mean in function definitions.

Summary: *args collects positional arguments as a tuple; **kwargs collects keyword arguments as a dict. You can also unpack when calling a function.

def func(a, b, *args, **kwargs):
    print(a, b)
    print(args)
    print(kwargs)

func(1, 2, 3, 4, x=10, y=20)
# (1, 2)
# (3, 4)
# {'x': 10, 'y': 20}

 

Data Structures & Built‑ins

In many interviews you’ll get questions that test how well you know Python’s built-in data structures (lists, dicts, sets), their operations, performance trade-offs, and some common idioms.

 

6. How would you remove duplicates from a list while maintaining order?

Common wrong answer: list(set(seq)) — this loses order. Two good solutions:

def unique_preserve_order(seq):
    seen = set()
    result = []
    for x in seq:
        if x not in seen:
            seen.add(x)
            result.append(x)
    return result

# Or on Python 3.7+: list(dict.fromkeys(seq))

 

7. What is list comprehension? Give an example.

Example:

squares = [x*x for x in range(10) if x % 2 == 0]

 

8. Explain the difference between is and == in Python

Identity vs equalityis checks whether two references point to the same object; == checks value equality (via __eq__).

 

9. What’s a generator in Python, and how is it different from a list?

Generators are iterators defined with yield or generator expressions. They evaluate lazily and are memory efficient compared to lists.

def my_gen(n):
    for i in range(n):
        yield i*i

for val in my_gen(5):
    print(val)

 

10. Explain shallow copy vs deep copy.

import copy
original = [[1,2], [3,4]]
shallow = copy.copy(original)
deep = copy.deepcopy(original)

shallow[0][0] = 9
print(original)  # [[9,2], [3,4]]

deep[1][1] = 8
print(original)  # still [[9,2], [3,4]]

 

3. Functions, Modules & Scope

These questions probe your understanding of how Python binds variables, the module system, first-class functions, etc.

 

11. What does the self keyword mean in Python methods?

Short: the conventional name for the instance reference passed to instance methods. It’s not a keyword but a strong convention.

self is a conventional name for the first parameter of an instance method. It refers to the instance on which the method is called.

 

class Foo:
def __init__(self, value):
self.value = value
def show(self):
print(self.value)

f = Foo(10)
f.show() # implicitly: Foo.show(f)

12. Explain what a module and a package are in Python.

A module is a single .py file. A package is a directory of modules (historically containing __init__.py) that creates a namespace hierarchy.

  • A module is a single file (with .py extension) containing Python code (functions, classes, variables) that can be imported. GeeksforGeeks+1

  • A package is a directory containing a special __init__.py file (in older versions) and other modules or sub-packages. It lets you create a hierarchical namespace. GeeksforGeeks


Tip: You might mention how relative imports work inside packages, or the effect of __init__.py in making a directory a package (though newer Python versions don’t strictly require it).
Pitfall: Confusing modules with packages or omitting directory structure.

 

13. How do default argument values behave in Python functions? Are there any pitfalls?

Default argument values are evaluated once at function definition time, not each time the function is called.

  • If the default is a mutable object (e.g., list or dict), it can persist across calls, possibly leading to unexpected behaviour.
    Example:

def f(a, my_list=[]):
my_list.append(a)
return my_list

print(f(1)) # [1]
print(f(2)) # [1, 2] — same list used again

To avoid this, use None as default and assign inside function:

def f(a, my_list=None):
if my_list is None:
my_list = []
my_list.append(a)
return my_list
Tip: Mention how keyword-only arguments can help, or use immutable defaults.
Pitfall: Saying “defaults are evaluated at call time”.
 

 

14. How does Python pass arguments to functions — by value or by reference?

  • Python uses a model often described as pass by object reference (or call by sharing).

  • The function receives a reference to the object. If the object is mutable and you modify it, the caller sees the change; if it’s immutable you cannot change the object itself (though you may rebind).

 

4. Object‑Oriented Programming (OOP)

Python supports OOP and many interviews will ask about class structure, inheritance, special methods, etc.

 

15. What are the four pillars of OOP and how do they map to Python?

  • Encapsulation — attributes and methods in classes; use naming conventions like _private.
  • Abstraction — expose simple interfaces and hide implementation details; duck typing helps.
  • Inheritance — subclassing to reuse code.
  • Polymorphism — different object types sharing the same interface; operator overloading via dunder methods.

 

16.What is __init__() in a Python class?

__init__(self, …) is the initializer method that is called when a new instance of the class is created. It sets up initial state of the object (assign instance variables, etc.).

Example:

class Person:
def __init__(self, name, age):
self.name = name
self.age = age

p = Person(“Alice”, 30)

17. Explain how method overriding and multiple inheritance work in Python

  • Method overriding: A subclass defines a method with the same name as one in its base class; when invoked on the subclass instance, the subclass’s version is used.

  • Multiple inheritance: A class can inherit from multiple base classes: class C(A, B): ….

  • Python uses the C3 linearization algorithm (MRO – method resolution order) to determine which method to call when multiple inheritance is involved. You can inspect via ClassName.__mro__ or mro() method.

  • Example:

    class A:
    def hello(self):
    print(“Hello from A”)

    class B:
    def hello(self):
    print(“Hello from B”)

    class C(A, B):
    pass

    c = C()
    c.hello() # prints “Hello from A” because A appears before B in C’s MRO
    print(C.__mro__)

 

5. Advanced / Intermediate Topics

These topics separate good candidates from great ones. Expect at least one question here if you interview for a strong Python role.

 

18. What are decorators in Python? Provide an example.

Decorators take a function and return a new function that adds behaviour. They are used for logging, caching, authentication, and more.

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Before calling", func.__name__)
        result = func(*args, **kwargs)
        print("After calling", func.__name__)
        return result
    return wrapper

@my_decorator
def say_hello(name):
    print(f"Hello, {name}")

say_hello("Alice")

 

19. What is the with statement (context manager) and how does it work?

The with statement uses objects that implement __enter__ and __exit__. It guarantees cleanup even when exceptions occur.

class MyContext:
    def __enter__(self):
        print("Entering")
        return self
    def __exit__(self, exc_type, exc_value, traceback):
        print("Exiting")
        if exc_type:
            print("Exception:", exc_value)
        return False

with MyContext():
    print("Inside")

 

20. Explain generator expressions vs list comprehensions, and when you might choose one over the other.

A list comprehension builds the entire list in memory: [x*x for x in range(1000000)].

A generator expression builds items one by one as needed: (x*x for x in range(1000000)).

Use a generator when you expect many items and you don’t need all of them at once (or want to pipe items through further operations) — memory efficient.

 

21. What is a closure in Python?

A closure occurs when a function (“inner”) captures variables from its enclosing lexical scope (“outer”), and retains those values even when the outer function has finished executing.

Example:

def make_multiplier(factor):
    def multiplier(x):
        return x * factor
    return multiplier

double = make_multiplier(2)
print(double(10))  # 20

 

6. Performance, Memory & Internals

This is where Python-specific wisdom pays off. Strong candidates show awareness of how Python works under the hood.

 

22. How does garbage collection and memory management work in Python?

  • In CPython, most object memory is released through reference counting: when the reference count drops to zero, the object is deallocated.

  • To handle reference cycles (objects referring to each other), Python uses a cyclic garbage collector (in module gc) that periodically looks for unreachable cycles and cleans them up.

  • Memory fragmentation and the Python memory allocator (pymalloc) are deeper topics, may come up in advanced interviews.

 

23. Why might list comprehensions or built-in operations be faster than equivalent manual loops in Python?

Built-ins and comprehensions often execute operations in C loops (inside the interpreter) rather than interpreting each iteration in Python bytecode. This reduces per-iteration overhead.

Example: [x*x for x in range(1000000)] is faster than:

result = []
for x in range(1000000):
result.append(x*x)
 

Also using libraries like numpy shifts loops into C/Fortran, offering large speedups (though this is more about libraries).

 

24. What is the Global Interpreter Lock (GIL) in Python and how does it affect multithreading?

The GIL prevents multiple native threads from executing Python bytecode simultaneously in CPython. It limits CPU‑bound thread parallelism; use multiprocessing or native extensions for parallel CPU work. Threads are still excellent for I/O concurrency.

 

25. How do you profile a Python program and locate performance bottlenecks?

Use cProfile, timeit, tracemalloc, and third‑party tools like line_profiler to find bottlenecks. Focus on algorithmic improvements before micro‑optimisations.

 

7. Code Challenges & Problem Solving

Example problems, answers and notes.

 

26. Write a Python function to check if a given string is a palindrome.

def is_palindrome(s: str) -> bool:
    filtered = ''.join(ch.lower() for ch in s if ch.isalnum())
    return filtered == filtered[::-1]

print(is_palindrome("A man, a plan, a canal: Panama"))  # True

 

27. Given two lists, find the common elements.

def common_elements(list1, list2):
    set2 = set(list2)
    return [x for x in list1 if x in set2]

print(common_elements([1,2,3,4], [3,4,5,6]))  # [3,4]

 

28. How would you implement a custom iterator class in Python?

class CountDown:
    def __init__(self, start):
        self.current = start
    def __iter__(self):
        return self
    def __next__(self):
        if self.current <= 0:
            raise StopIteration
        val = self.current
        self.current -= 1
        return val

for n in CountDown(5):
    print(n)

 

29. Write a function to merge two sorted lists into a single sorted list.

def merge_sorted(a, b):
    i, j = 0, 0
    merged = []
    while i < len(a) and j < len(b):
        if a[i] <= b[j]:
            merged.append(a[i]); i += 1
        else:
            merged.append(b[j]); j += 1
    merged.extend(a[i:])
    merged.extend(b[j:])
    return merged

print(merge_sorted([1,3,5], [2,4,6]))

 

8. Interview Strategy: How to Prepare & How to Answer

Preparation tips

  • Review language fundamentals and idioms.
  • Practice coding problems, both easy and moderately hard.
  • Know libraries relevant to the role (e.g., pandas/numpy for data roles).
  • Learn profiling, the GIL, and memory behaviour for advanced roles.

How to answer in an interview

  1. Clarify constraints and edge cases.
  2. Explain your approach before coding.
  3. Write readable code and test edge cases.
  4. Mention complexity and potential optimisations.

Final thought: a clear, correct, and explained answer beats a rushed, untested one.

 

Conclusion

Preparing for a Python interview is about conceptual fluency, clear explanations, and writing idiomatic code. Use this guide as a checklist: practise the areas you’re weak at, test your solutions, and rehearse explaining your reasoning aloud.