RMRM Full Stack & AI Engineer · All questions · Roadmaps
Languages · interview questions

Python Interview Questions

Common Python technical interview questions spanning beginner to advanced, covering core language features, data structures, OOP, concurrency, and performance.

1. What are Python's key features that distinguish it from other languages?

beginner

Python is dynamically typed, interpreted, and emphasizes readability via indentation-based syntax. It supports multiple paradigms (OOP, functional, procedural), has a vast standard library, and uses automatic memory management via garbage collection.

2. What is the difference between a list and a tuple in Python?

beginner

Lists are mutable (elements can be changed after creation) while tuples are immutable. Tuples are generally faster, can be used as dictionary keys, and are preferred for heterogeneous fixed data; lists are preferred for homogeneous collections that need modification.

3. What are Python's mutable vs immutable types? Give examples.

beginner

Immutable types cannot be changed after creation: int, float, str, tuple, frozenset, bytes. Mutable types can be modified in place: list, dict, set, bytearray. Mutability affects how objects behave when passed to functions and used as dictionary keys.

4. How does Python manage memory?

beginner

Python uses reference counting as its primary memory management mechanism; when an object's reference count drops to zero it is deallocated. A cyclic garbage collector handles reference cycles that reference counting alone cannot resolve.

5. What is the difference between '==' and 'is' in Python?

beginner

'==' compares values (equality), while 'is' compares object identity (whether two variables point to the exact same object in memory). For example, two separate lists with identical contents are '==' but not 'is'.

6. What are *args and **kwargs and when would you use them?

beginner

*args collects extra positional arguments into a tuple, and **kwargs collects extra keyword arguments into a dictionary. They are used to write functions that accept a variable number of arguments, enabling flexible APIs and decorator patterns.

7. What is a Python decorator and how does it work?

intermediate

A decorator is a callable that wraps another function to extend or modify its behavior without changing its source code. It is applied with the '@decorator' syntax and works by accepting a function, returning a new function that typically calls the original internally.

8. Explain list comprehensions vs generator expressions.

intermediate

List comprehensions ([x for x in iterable]) eagerly evaluate and store the full result in memory. Generator expressions ((x for x in iterable)) are lazy — they yield items one at a time, making them memory-efficient for large or infinite sequences.

9. What is the GIL (Global Interpreter Lock) and how does it affect concurrency?

intermediate

The GIL is a mutex in CPython that allows only one thread to execute Python bytecode at a time, preventing true parallel execution of CPU-bound threads. For CPU-bound tasks the multiprocessing module bypasses the GIL; for I/O-bound tasks threading or asyncio work well despite it.

10. What is the difference between shallow copy and deep copy?

intermediate

A shallow copy (copy.copy()) creates a new object but references the same nested objects as the original. A deep copy (copy.deepcopy()) recursively copies all nested objects, so modifications to the copy do not affect the original at any level.

11. How does Python's 'with' statement and context manager protocol work?

intermediate

The 'with' statement calls __enter__ on entry and guarantees __exit__ is called on exit, even if an exception occurs. It is used for resource management (files, locks, DB connections) and can be created via a class implementing __enter__/__exit__ or the contextlib.contextmanager decorator.

12. What are Python generators and what is the 'yield' keyword?

intermediate

A generator is a function that uses 'yield' to produce a sequence of values lazily, suspending execution between calls. Each call to next() resumes from where it left off, making generators memory-efficient for pipelines or large datasets.

13. Explain method resolution order (MRO) and the super() function.

intermediate

MRO defines the order in which Python searches classes for a method in an inheritance hierarchy, determined by the C3 linearization algorithm. super() follows the MRO to call the next class's method, enabling cooperative multiple inheritance without hardcoding class names.

14. What is the difference between @staticmethod and @classmethod?

intermediate

@staticmethod defines a method that receives no implicit first argument — it behaves like a plain function scoped to the class. @classmethod receives the class itself as the first argument (cls) and is commonly used for factory methods or accessing/modifying class-level state.

15. How do Python's __slots__ work and when should you use them?

advanced

__slots__ replaces the per-instance __dict__ with a fixed set of descriptors, reducing memory usage and slightly speeding up attribute access. Use them when creating many instances of a class with a known fixed set of attributes and memory efficiency matters.

16. Explain asyncio: what is the event loop and how do async/await work?

advanced

asyncio's event loop runs coroutines cooperatively — when a coroutine hits 'await', it suspends and yields control back to the loop, allowing other coroutines to run. async/await enables non-blocking I/O-bound concurrency in a single thread without the complexity of callbacks.

17. What are metaclasses in Python and when would you use one?

advanced

A metaclass is the 'class of a class' — it controls how classes themselves are created, allowing you to modify class attributes, enforce interfaces, or register classes automatically. You use them for frameworks, ORMs, or enforcing coding contracts at class-definition time.

18. How does Python's descriptor protocol work?

advanced

A descriptor is an object that defines __get__, __set__, or __delete__, which Python calls when the attribute is accessed on a class or instance. Properties, classmethod, staticmethod, and ORM field types all leverage the descriptor protocol under the hood.

19. What is the difference between multiprocessing, threading, and asyncio? When do you choose each?

advanced

Use threading for I/O-bound tasks where the GIL is less limiting; use multiprocessing for CPU-bound tasks to achieve true parallelism across cores; use asyncio for high-concurrency I/O-bound tasks (e.g., thousands of network connections) with minimal overhead and a single-threaded model.

20. How would you profile and optimize a slow Python function?

advanced

Start with cProfile or the timeit module to identify bottlenecks, then examine algorithmic complexity before micro-optimizing. Common optimizations include using built-in functions, replacing loops with NumPy vectorization, caching with functools.lru_cache, and moving hot paths to C extensions or Cython.

Practice these out loud with an AI interviewer that grills you and grades your answers.
Open the app — free to start

© RM Full Stack & AI Engineer · All interview questions · Roadmaps · Open the app