Skip to main contentOpteroAIBeta

Python interview questions

Python interview questions covering language fundamentals, data structures, the standard library, concurrency, and common pitfalls.

12 questions
4 easy5 medium3 hard

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

easy
How to approach thisLists are mutable (can be modified after creation), tuples are immutable. Tuples are hashable (can be dict keys or set members) if all their elements are hashable. Tuples are slightly faster for iteration and use less memory. Use tuples for fixed collections (coordinates, database rows) and lists for dynamic collections.

2.Explain Python's Global Interpreter Lock (GIL). How does it affect multithreading?

hard
How to approach thisThe GIL is a mutex that allows only one thread to execute Python bytecode at a time. This means CPU-bound tasks do not benefit from threading. Use multiprocessing for CPU-bound work (each process has its own GIL) and threading for I/O-bound work (the GIL is released during I/O). Alternatively, use asyncio for concurrent I/O.

3.What are decorators in Python, and how do they work?

medium
How to approach thisA decorator is a function that takes another function and returns a modified version. The @decorator syntax is syntactic sugar for func = decorator(func). Common uses: logging, access control, caching (functools.lru_cache), timing. Always use functools.wraps to preserve the original function's name and docstring.

4.Explain the difference between deepcopy and shallow copy.

medium
How to approach thisA shallow copy (copy.copy or list.copy()) creates a new object but references the same nested objects. A deep copy (copy.deepcopy) recursively copies all nested objects. Shallow copies are faster but mutations to nested objects affect both copies. Use deep copy when you need fully independent copies of complex nested structures.

5.What are generators in Python, and why are they useful?

medium
How to approach thisGenerators are functions that use yield instead of return. They produce values lazily (one at a time), which is memory-efficient for large sequences. A generator expression (x for x in range(n)) is the generator equivalent of a list comprehension. Use them when processing large files, database results, or infinite sequences.

6.How does Python's garbage collection work?

hard
How to approach thisPython uses reference counting as its primary mechanism: when an object's reference count drops to zero, it is immediately freed. A cyclic garbage collector handles reference cycles (two objects referencing each other). You can interact with it via the gc module. Avoid circular references in performance-critical code.

7.What is the difference between __str__ and __repr__?

easy
How to approach this__str__ returns a human-readable string for end users (called by str() and print()). __repr__ returns an unambiguous string for developers (called by repr() and in the REPL). Ideally, __repr__ output should be valid Python that recreates the object. Always implement __repr__; __str__ is optional.

8.Explain Python's method resolution order (MRO) for multiple inheritance.

hard
How to approach thisPython uses the C3 linearization algorithm to determine the order in which base classes are searched when calling a method. You can check it with ClassName.__mro__ or ClassName.mro(). The algorithm ensures each class appears once and respects the ordering of base classes. Use super() to follow the MRO correctly.

9.What are context managers, and how do you create one?

medium
How to approach thisContext managers define setup and teardown logic for a with statement. Create one by defining __enter__ and __exit__ methods on a class, or use the contextlib.contextmanager decorator with a generator function. Common uses: file handling, database connections, locks, temporary state changes.

10.How would you handle a mutable default argument in a function?

easy
How to approach thisDefault arguments are evaluated once at function definition time, not at each call. So def f(items=[]) shares the same list across all calls. Fix by using None as the default and creating a new object inside the function: def f(items=None): items = items if items is not None else []. This is one of the most common Python interview gotchas.

11.What is the difference between async/await and threading in Python?

medium
How to approach thisasync/await (asyncio) uses cooperative multitasking on a single thread, switching tasks at await points. Threading uses OS threads with preemptive scheduling. asyncio has lower overhead and avoids race conditions for I/O-bound work. Threading is simpler for CPU-bound work or when calling blocking libraries that do not support async.

12.Explain list comprehensions vs. map/filter. When would you prefer one over the other?

easy
How to approach thisList comprehensions ([x*2 for x in items if x > 0]) are more Pythonic and readable for simple transformations. map/filter are useful when you already have a named function to apply. Avoid nested list comprehensions beyond two levels; they become unreadable. For large datasets, use generator expressions instead of list comprehensions to save memory.

Prepare further

More interview topics