Top 50 Python Interview Questions & Answers
Prepare for Python interviews with 50 clear answers on data structures, decorators, generators, OOP, the GIL, asyncio, testing and tooling.
Language Basics
Q1. What is Python and what kind of language is it?
Python is a high-level, general-purpose language with dynamic and strong typing. CPython, the standard implementation, compiles source code to bytecode and runs it on a virtual machine.
Q2. What is the difference between a list and a tuple?
A list is mutable and a tuple is immutable. A tuple can be used as a dictionary key if everything inside it is hashable, and it signals that the data should not change.
Q3. What is the difference between == and is?
== compares values by calling __eq__. is checks whether two names point to the same object, so use it for singletons, as in x is None.
Q4. What are mutable and immutable types?
Mutable objects such as list, dict and set can change in place. Immutable objects such as int, str and tuple cannot, so an apparent change creates a new object.
Q5. How does Python pass arguments to functions?
Python passes object references by assignment. Changing a mutable argument in place is visible to the caller, while rebinding the parameter name inside the function is not.
Q6. Why is a mutable default argument a problem?
Default values are evaluated once, when the function is defined, so def f(x=[]) shares one list across calls. Use x=None and create the list inside the function.
Q7. What do *args and **kwargs do?
*args collects extra positional arguments into a tuple, and **kwargs collects extra keyword arguments into a dictionary. The same symbols unpack values when calling a function.
Q8. What is the LEGB rule?
It is the order Python uses to look up a name: Local, Enclosing, Global, then Built-in. Use nonlocal or global to assign to a name in an outer scope.
Q9. What is the difference between a shallow copy and a deep copy?
A shallow copy creates a new container that still refers to the same inner objects. copy.deepcopy() recursively copies the inner objects too.
Q10. What are f-strings?
F-strings, such as f"Total: {price:.2f}", embed expressions directly in a string literal. They are usually the clearest way to format text in modern Python.
Data Structures & Functions
Q11. How does a Python dictionary work internally?
A dictionary is a hash table, which gives average O(1) lookup, insert and delete. Since Python 3.7, dictionaries are guaranteed to keep insertion order.
Q12. What can be used as a dictionary key?
Any hashable object, meaning its hash never changes during its lifetime and it supports equality checks. Strings, numbers and tuples of hashable values work, but lists do not.
Q13. When should you use a set instead of a list?
Use a set for fast membership tests and removing duplicates, since in is O(1) on average compared with O(n) for a list. Sets do not keep order or allow duplicates.
Q14. What is a list comprehension?
It is a compact way to build a list, as in [x * 2 for x in nums if x > 0]. Dictionary and set comprehensions use the same idea with curly braces.
Q15. What is the difference between a generator and a list?
A list stores every item in memory. A generator produces items one at a time using yield or a generator expression, so it can handle large or endless sequences with little memory.
Q16. What is the difference between an iterable and an iterator?
An iterable can return an iterator through __iter__. An iterator returns the next item through __next__ and raises StopIteration when it runs out.
Q17. What is a decorator?
A decorator is a callable that takes a function and returns a replacement, often to add logging, caching or access checks. Use functools.wraps so the wrapped function keeps its name and docstring.
Q18. What is a closure?
A closure is an inner function that remembers variables from its enclosing scope after the outer function has returned. Decorators commonly rely on closures.
Q19. What is a lambda function?
A lambda is a small anonymous function limited to one expression, such as key=lambda u: u.age. Use def when the logic needs a name or more than one step.
Q20. What does functools.lru_cache do?
It stores results of a function by its arguments and returns the stored result on repeat calls. The arguments must be hashable, and old entries are dropped once maxsize is reached.
Object-Oriented Python
Q21. What does self mean?
self is the conventional name for the instance a method was called on. Python passes it automatically as the first argument of an instance method.
Q22. What is the difference between __init__ and __new__?
__new__ creates and returns the instance, and __init__ then initializes it. You normally only override __new__ for immutable types or to control instance creation.
Q23. What is the difference between instance, class and static methods?
An instance method receives self. A @classmethod receives the class as cls, which suits alternative constructors. A @staticmethod receives neither and is a plain function kept in the class namespace.
Q24. What is the Method Resolution Order (MRO)?
It is the order Python searches classes for an attribute, calculated with C3 linearization. You can inspect it with ClassName.__mro__, and super() follows it.
Q25. What are dunder methods?
Dunder (double underscore) methods let a class work with Python syntax and built-ins. For example, __len__ supports len(), __eq__ supports ==, and __repr__ controls the debug display.
Q26. What is the difference between __str__ and __repr__?
__str__ gives a readable form for users, and __repr__ gives an unambiguous form for developers. If __str__ is missing, Python falls back to __repr__.
Q27. What does @property do?
It lets a method be read like an attribute, so you can add validation or calculation later without changing how callers use the class. A matching setter can control assignment.
Q28. What are dataclasses?
@dataclass generates methods such as __init__, __repr__ and __eq__ from annotated fields. Options like frozen=True and slots=True make instances immutable or more memory efficient.
Q29. What are abstract base classes?
A class based on abc.ABC can mark methods with @abstractmethod. Python then refuses to instantiate any subclass that has not implemented all of them.
Q30. What is duck typing?
Python cares about what an object can do rather than its declared type. Anything with a read() method can be used where file-like behaviour is expected, and typing.Protocol can describe that shape for type checkers.
Concurrency & Internals
Q31. What is the GIL?
The Global Interpreter Lock lets only one thread run Python bytecode at a time in a standard CPython build. It limits threads for CPU work, though Python 3.13 and later offer an optional free-threaded build.
Q32. When should you use threads, processes or asyncio?
Use threading or asyncio for I/O-bound work such as network calls, and multiprocessing for CPU-bound work that needs multiple cores. asyncio suits many concurrent connections when your libraries support it.
Q33. What is the difference between concurrency and parallelism?
Concurrency means managing several tasks that overlap in time. Parallelism means running tasks at the same instant on multiple CPU cores.
Q34. What do async and await do?
async def defines a coroutine, and await pauses it until another awaitable finishes, letting the event loop run other tasks. It is cooperative, so blocking code still stalls the loop.
Q35. How do you run several async tasks at once?
Use asyncio.TaskGroup (Python 3.11+) or asyncio.gather(). Both run tasks concurrently, and a TaskGroup also cancels the remaining tasks if one fails.
Q36. How does Python manage memory?
CPython mainly uses reference counting, freeing an object when its count reaches zero. A cyclic garbage collector, available through the gc module, handles reference cycles.
Q37. What is a context manager?
An object used with with that defines __enter__ and __exit__, so cleanup runs even if an error occurs. Files and locks are common examples, and contextlib.contextmanager builds one from a generator.
Q38. How does Python exception handling work?
Code runs in try, matching errors go to except, else runs if nothing failed, and finally always runs. Catch specific exceptions rather than a bare except.
Q39. What does __slots__ do?
It declares a fixed set of attributes and removes the per-instance __dict__ by default. This saves memory when you create very many objects, but you cannot add other attributes.
Q40. What are weak references used for?
A weakref refers to an object without keeping it alive. It is useful for caches and observers, where an entry should not stop the object being garbage collected.
Modules, Tooling & Testing
Q41. What does if __name__ == "__main__" do?
It runs a block only when the file is executed directly, not when it is imported. This keeps a module safe to import while still allowing it to work as a script.
Q42. What is the difference between a module and a package?
A module is a single .py file. A package is a directory of modules, usually with an __init__.py, that can be imported as a group.
Q43. Why use a virtual environment?
A virtual environment, created with python -m venv .venv, gives each project its own packages and versions, which prevents conflicts between projects and the system Python.
Q44. What are type hints?
Annotations such as def add(a: int, b: int) -> int document expected types. Python does not enforce them at runtime, but tools like mypy and Pyright can check them.
Q45. What is a circular import and how do you fix it?
It happens when two modules import each other while still loading, which can leave names undefined. Fix it by moving shared code to a third module or importing inside the function.
Q46. What is the difference between pytest and unittest?
unittest is in the standard library and uses test classes. pytest is a third-party tool with plain assert statements, fixtures, parametrization and a large plugin ecosystem.
Q47. What is a pytest fixture?
A fixture is a reusable function that prepares test data or resources and is requested by name as a test argument. Code after yield in a fixture handles the cleanup.
Q48. How do you mock an external call in a test?
Use unittest.mock.patch to replace the object where it is looked up, so a test does not make a real network or database call. You can then check how the mock was used.
Q49. What is PEP 8?
PEP 8 is Python's style guide, covering naming, indentation, line length and layout. Tools such as Ruff and Black can check or apply a consistent style automatically.
Q50. How do you find a performance problem in Python code?
Measure before changing anything. Use cProfile to find slow functions and timeit for small comparisons, then improve the algorithm or data structure before micro-optimizing.