Interview Preparation
💼 Python & Algorithms
Practice coding logic, data structure puzzles, and algorithmic questions for Python devs.
No questions match your search. Try a different keyword.
All Python & Algorithms Interview Questions (41 total)
This is the complete question bank powering the practice tool above, covering Python syntax, data structures, and common algorithm interview problems. Open any item below to see the full written answer.
1. What is Python and what are some of its key features? (Easy)
Python is a high-level, interpreted, general-purpose programming language known for its readable syntax. Key features include dynamic typing, automatic memory management, a large standard library, support for multiple programming paradigms (procedural, object-oriented, functional), and an extensive third-party package ecosystem.
2. What is the difference between a compiled and an interpreted language, and where does Python fit? (Medium)
A compiled language is translated entirely into machine code before execution, producing a standalone executable. An interpreted language is executed line by line by an interpreter at runtime. Python is technically both: source code is first compiled into bytecode, which is then executed by the Python interpreter (the CPython virtual machine).
3. What is PEP 8? (Easy)
PEP 8 is Python's official style guide, outlining conventions for formatting code such as indentation, naming conventions, line length, and whitespace usage. Following PEP 8 makes Python code more consistent and readable across different projects and teams.
4. What is the difference between a shallow copy and a deep copy in Python? (Medium)
A shallow copy, created with copy.copy(), creates a new outer object but still references the same nested objects as the original. A deep copy, created with copy.deepcopy(), recursively copies all nested objects as well, so changes to nested data in the copy do not affect the original.
5. What are Python decorators? (Medium)
A decorator is a function that takes another function as input and extends or modifies its behavior without permanently changing its source code, using the @decorator_name syntax. They are commonly used for logging, access control, timing, and caching by wrapping the original function's execution.
6. What is the difference between *args and **kwargs in Python? (Medium)
*args allows a function to accept any number of positional arguments, which are collected into a tuple inside the function. **kwargs allows a function to accept any number of keyword arguments, which are collected into a dictionary, letting functions handle flexible or variable input signatures.
7. What is a list comprehension in Python? (Easy)
A list comprehension is a concise syntax for creating a new list by applying an expression to each item in an iterable, optionally with a filtering condition, for example [x*x for x in range(10) if x % 2 == 0]. It is generally more readable and faster than building the same list with an explicit for loop.
8. How does Python implement encapsulation, since it doesn't have true private access modifiers? (Medium)
Python uses naming conventions rather than strict access modifiers: a single leading underscore (_variable) signals that an attribute is intended to be protected/internal by convention, while a double leading underscore (__variable) triggers name mangling, making it harder (though not impossible) to access from outside the class.
9. What is the difference between a class method, a static method, and an instance method in Python? (Medium)
An instance method takes 'self' as its first parameter and can access and modify instance-specific data. A class method, marked with @classmethod, takes 'cls' as its first parameter and operates on the class itself rather than an instance. A static method, marked with @staticmethod, takes neither and behaves like a regular function that's just logically grouped inside the class.
10. What is method resolution order (MRO) in Python? (Medium)
Method Resolution Order defines the sequence in which Python looks up methods and attributes across a class hierarchy, particularly important with multiple inheritance. Python uses the C3 linearization algorithm to compute a consistent order, which can be inspected using ClassName.__mro__ or ClassName.mro().
11. What is the difference between __init__ and __new__ in Python? (Medium)
__new__ is a static method responsible for actually creating and returning a new instance of a class, called before __init__. __init__ is an instance method responsible for initializing the newly created object's attributes; it does not return anything and operates on an already-existing instance.
12. What is the difference between a list and a tuple in Python? (Easy)
A list is mutable, meaning its elements can be changed, added, or removed after creation, and it is defined with square brackets. A tuple is immutable, meaning its contents cannot be changed once created, and it is defined with parentheses; tuples are also generally faster and can be used as dictionary keys, unlike lists.
13. How do you remove duplicate elements from a Python list? (Medium)
The most common way is to convert the list into a set, since sets automatically discard duplicates, and then convert it back into a list, for example list(set(my_list)). Note this does not preserve original order; to preserve order, you can use dict.fromkeys(my_list) instead, since dictionaries in modern Python maintain insertion order.
14. What is list slicing in Python and how does it work? (Easy)
List slicing extracts a sublist using the syntax list[start:stop:step], where start is the inclusive starting index, stop is the exclusive ending index, and step is the interval between elements. Omitting any of these uses default values, and negative indices count from the end of the list.
15. Why would you use a tuple instead of a list in Python? (Medium)
Tuples are preferred when the data should not change after creation, providing safety against accidental modification. They are also more memory-efficient and slightly faster than lists, and because they are hashable, they can be used as dictionary keys or stored in sets, which lists cannot.
16. What is tuple unpacking in Python? (Medium)
Tuple unpacking is the process of assigning the individual elements of a tuple to multiple variables in a single statement, for example a, b, c = (1, 2, 3). Python also supports extended unpacking with the * operator to capture multiple remaining elements into a list, such as first, *rest = (1, 2, 3, 4).
17. Can a tuple contain mutable elements, and what does that mean for its immutability? (Medium)
Yes, a tuple can contain mutable objects like lists. The tuple itself remains immutable in that you cannot reassign which objects it references, but if one of those objects is mutable, its internal contents can still be changed, meaning immutability applies to the tuple's structure, not necessarily to everything it contains.
18. What is a dictionary in Python and what are its key characteristics? (Easy)
A dictionary is an unordered (prior to Python 3.7) or insertion-ordered (3.7+) collection of key-value pairs, defined with curly braces. Keys must be unique and hashable (such as strings, numbers, or tuples), while values can be of any type, and lookups by key run in average O(1) time.
19. How do you safely access a dictionary value that might not exist, without raising a KeyError? (Easy)
You can use the .get() method, which returns None or a specified default value if the key is missing, for example my_dict.get('key', 'default'). Alternatively, you can check membership first with 'if key in my_dict' before accessing it, or use a try/except block to catch the KeyError.
20. What is a dictionary comprehension in Python? (Medium)
A dictionary comprehension is a concise way to build a dictionary from an iterable using the syntax {key_expr: value_expr for item in iterable}, optionally with a filtering condition. For example, {x: x**2 for x in range(5)} creates a dictionary mapping numbers to their squares.
21. What is the difference between a parameter and an argument in Python functions? (Easy)
A parameter is the variable name listed in a function's definition that acts as a placeholder for input, for example 'name' in def greet(name). An argument is the actual value passed into the function when it is called, for example the string 'Alice' in greet('Alice').
22. What is a lambda function in Python? (Easy)
A lambda function is a small, anonymous, single-expression function defined using the lambda keyword, for example lambda x, y: x + y. Lambdas are commonly used for short, throwaway functions passed as arguments to functions like sorted(), map(), or filter(), where defining a full named function would be unnecessarily verbose.
23. What is the difference between a generator function and a regular function in Python? (Medium)
A regular function computes and returns its entire result at once using return. A generator function uses the yield keyword to produce a sequence of values lazily, one at a time, pausing its state between each call, which makes it much more memory-efficient for processing large or infinite sequences.
24. What are default arguments in Python functions, and what is a common pitfall with them? (Medium)
Default arguments let you specify a fallback value for a parameter if no argument is provided during the call, for example def greet(name='Guest'). A common pitfall is using a mutable object like a list or dictionary as a default value, since it is created only once and shared across all calls, potentially causing unexpected shared state between function calls.
25. What is recursion and what two components must every recursive function have? (Easy)
Recursion is a technique where a function calls itself to solve a smaller instance of the same problem. Every recursive function needs a base case that stops the recursion and returns a result directly, and a recursive case that breaks the problem down and calls the function again with a smaller input, moving toward the base case.
26. What is the risk of using recursion for problems with very large input sizes? (Medium)
Deep recursion can lead to a stack overflow because each recursive call adds a new frame to the call stack, and most languages, including Python, impose a maximum recursion depth (Python's default is 1000). For problems that could recurse very deeply, an iterative solution or increasing the recursion limit is often safer.
27. What is the difference between recursion and iteration, and when might you prefer one over the other? (Medium)
Recursion solves a problem by having a function call itself with smaller inputs, often producing simpler, more readable code for naturally recursive problems like tree traversal. Iteration solves a problem using loops, which is generally more memory-efficient since it avoids the overhead of the call stack, making it preferable for simple repetitive tasks or very large inputs.
28. What is the difference between linear search and binary search? (Easy)
Linear search checks each element of a collection one by one until it finds the target, working on unsorted data with O(n) time complexity. Binary search repeatedly divides a sorted collection in half, comparing the target to the middle element, achieving a much faster O(log n) time complexity but requiring the data to already be sorted.
29. What is the time complexity of binary search and why? (Medium)
Binary search runs in O(log n) time because each comparison eliminates half of the remaining search space. Starting with n elements, after k comparisons only n/2^k elements remain, so the number of steps needed to narrow down to one element is log base 2 of n.
30. What is the difference between bubble sort and merge sort in terms of approach and efficiency? (Medium)
Bubble sort repeatedly steps through a list, swapping adjacent elements that are out of order, running in O(n^2) time in the average and worst case, making it inefficient for large datasets. Merge sort uses a divide-and-conquer approach, recursively splitting the list in half, sorting each half, and merging them back together, achieving a more efficient O(n log n) time complexity.
31. What is quicksort and what is its average versus worst-case time complexity? (Medium)
Quicksort is a divide-and-conquer sorting algorithm that selects a 'pivot' element, partitions the array so smaller elements go left and larger elements go right of the pivot, then recursively sorts each partition. Its average time complexity is O(n log n), but its worst case is O(n^2), which occurs when the pivot selection consistently results in highly unbalanced partitions, such as with an already-sorted array and a naive pivot choice.
32. What does it mean for a sorting algorithm to be 'stable'? (Medium)
A stable sorting algorithm preserves the relative order of elements that have equal keys. For example, if two records with the same value appear in a certain order before sorting, a stable algorithm guarantees they will appear in that same relative order after sorting, which matters when sorting by multiple criteria in sequence.
33. What is the difference between in-place and out-of-place sorting algorithms? (Medium)
An in-place sorting algorithm rearranges elements within the original data structure using only a small, constant amount of extra memory, such as quicksort or bubble sort. An out-of-place algorithm requires additional memory proportional to the input size to build a separate sorted structure, such as merge sort, which typically needs auxiliary arrays during the merge step.
34. What is Big O notation used for? (Easy)
Big O notation describes how an algorithm's running time or space requirements grow relative to the size of its input, in the worst case, as that input grows arbitrarily large. It allows developers to compare the scalability and efficiency of different algorithms independent of hardware or implementation details.
35. What is the difference between time complexity and space complexity? (Easy)
Time complexity measures how the running time of an algorithm grows as the input size increases. Space complexity measures how much additional memory an algorithm requires as the input size increases, including auxiliary data structures used during execution, separate from the input itself.
36. What is a stack and what is its typical use case? (Easy)
A stack is a linear data structure that follows the Last-In-First-Out (LIFO) principle, where elements are added and removed from the same end, called the top. Common use cases include function call management (the call stack), undo functionality in applications, and expression evaluation such as parsing balanced parentheses.
37. What is a queue and how does it differ from a stack? (Easy)
A queue is a linear data structure that follows the First-In-First-Out (FIFO) principle, where elements are added at the rear and removed from the front. This is the opposite of a stack's LIFO behavior, and queues are commonly used for task scheduling, print job management, and breadth-first traversal algorithms.
38. What is a hash table and how does it achieve fast average-case lookups? (Medium)
A hash table stores key-value pairs by applying a hash function to each key to compute an index into an underlying array (bucket), allowing average O(1) time for insertion, deletion, and lookup. Collisions, where two keys hash to the same index, are typically handled through techniques like chaining (storing multiple entries per bucket) or open addressing.
39. What is a binary tree, and what is a binary search tree? (Medium)
A binary tree is a hierarchical data structure in which each node has at most two children, commonly referred to as the left and right child. A binary search tree (BST) is a binary tree with the added property that for every node, all values in its left subtree are smaller and all values in its right subtree are larger, enabling efficient O(log n) average-case search, insertion, and deletion when the tree is balanced.
40. What is a linked list and what are its advantages over an array? (Medium)
A linked list is a linear data structure made of nodes, where each node holds a value and a reference (pointer) to the next node, without requiring contiguous memory. Its main advantage over an array is efficient O(1) insertion and deletion at any known position without shifting elements, though it sacrifices the O(1) random access that arrays provide.
41. What is a graph in data structures, and what are the two common ways to represent one? (Medium)
A graph is a data structure consisting of a set of nodes (vertices) connected by edges, which can be directed or undirected and weighted or unweighted, used to model relationships like networks or maps. The two common representations are an adjacency matrix, a 2D array indicating which vertices are connected, and an adjacency list, where each vertex stores a list of its neighboring vertices.
CodeMaster Academy