All question topics
Languages and roles16 questions

Python interview questions, with clear answers

Python questions in fresher interviews are less about tricky syntax and more about whether you understand how the language behaves: mutability, references, functions as objects and memory.

Each answer below gives the direct answer and a short example you could write on a whiteboard. The examples use Python 3.

Sample answers are examples written by Interview Fury. Adapt them to your own experience and say them in your own words.

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

Why they ask: It's the usual first Python question, and it leads into mutability.

Both are ordered sequences. A list is mutable — you can add, remove and change items — and is written with square brackets: [1, 2, 3]. A tuple is immutable and is written with parentheses: (1, 2, 3).

Because tuples can't change, they can be used as dictionary keys or set members (as long as their items are hashable), they're slightly lighter and faster, and they signal "this won't change" — like a coordinate (x, y). Use a list when the collection needs to change.

2.What are mutable and immutable types?

Mutable objects can be changed in place: lists, dictionaries, sets and most objects you create from your own classes. Immutable ones can't: int, float, str, tuple, frozenset and bytes.

It matters because Python variables are references. If two names point to the same list and you append through one, the other sees the change. "Changing" an immutable object — for example s += 'x' on a string — actually creates a new object.

3.What are *args and **kwargs?

They let a function accept a variable number of arguments. *args collects extra positional arguments into a tuple, and **kwargs collects extra keyword arguments into a dictionary:

def log(message, *args, **kwargs):
    print(message, args, kwargs)

log("hi", 1, 2, level="info")   # hi (1, 2) {'level': 'info'}

The same stars unpack values when you call a function: f(*my_list, **my_dict).

4.What is a decorator?

Why they ask: It tests whether you understand that functions are objects.

A decorator is a function that takes another function and returns a new function that adds behaviour around it, without changing the original code. The @ syntax applies it:

import time
from functools import wraps

def timed(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        print(f"{func.__name__} took {time.perf_counter() - start:.3f}s")
        return result
    return wrapper

@timed
def slow_add(a, b):
    return a + b

Real uses include logging, timing, access checks and caching (functools.lru_cache).

5.What are generators, and what does yield do?

A generator is a function that produces values one at a time instead of building the whole result in memory. yield hands back a value and pauses the function; the next request resumes it right after the yield.

def countdown(n):
    while n > 0:
        yield n
        n -= 1

for x in countdown(3):
    print(x)   # 3, 2, 1

Generators are lazy, so they can handle huge or even infinite sequences — like reading a large file line by line — while using very little memory. A generator expression looks like a list comprehension in parentheses: (x * x for x in range(10)).

Practise saying it, not just reading it

Rehearse these answers out loud with real-time AI help, tailored to your resume and the job description. Free minutes every day — no card required.

Try it free

6.What is the difference between a shallow copy and a deep copy?

A shallow copy creates a new outer object but shares the objects inside it. A deep copy copies everything, recursively.

import copy

a = [[1, 2], [3, 4]]
b = copy.copy(a)        # same as a[:] or list(a)
c = copy.deepcopy(a)

a[0].append(99)
print(b[0])   # [1, 2, 99] — shares the inner list
print(c[0])   # [1, 2]     — fully independent

Use a deep copy when the copy must not change when nested objects in the original change.

7.What is the GIL?

The Global Interpreter Lock is a lock in the standard CPython interpreter that lets only one thread run Python bytecode at a time. As a result, threads don't speed up CPU-heavy Python code — though they still help with I/O-bound work such as network calls, because the lock is released while a thread waits.

For CPU-bound parallel work, use multiprocessing (separate processes), or libraries like NumPy that do the heavy work outside the lock. Recent Python versions also offer an optional free-threaded build without the GIL, but the standard build still has it.

8.What is the difference between is and ==?

== checks whether two objects have equal values; is checks whether they are the very same object. [1, 2] == [1, 2] is True, but [1, 2] is [1, 2] is False, because they're two separate lists. Use is only for identity checks — most commonly x is None.

9.What are list comprehensions?

A compact way to build a list from an iterable, with an optional filter:

squares = [n * n for n in range(10) if n % 2 == 0]   # [0, 4, 16, 36, 64]

Python also has dictionary comprehensions ({k: v for k, v in pairs}) and set comprehensions ({x % 3 for x in nums}). They're usually faster and clearer than a loop with append(), but a comprehension that's hard to read is better written as a normal loop.

10.How does memory management work in Python?

CPython manages memory automatically. Every object has a reference count, and when it drops to zero — nothing refers to the object any more — the memory is freed straight away.

Reference counting can't free cycles, such as two objects that refer to each other, so a cyclic garbage collector (the gc module) runs periodically to find and free them. Small objects come from a specialised allocator for speed. As a developer, your main job is not to keep references longer than you need, such as an ever-growing global list.

11.Why should you avoid a mutable default argument?

Why they ask: It's a classic Python bug, and spotting it shows real experience.

Default values are evaluated once, when the function is defined, so a mutable default is shared between calls:

def add_item(item, items=[]):    # bug
    items.append(item)
    return items

add_item(1)   # [1]
add_item(2)   # [1, 2] — the same list again

The fix is to default to None and create the list inside the function:

def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

12.What are lambda functions?

A lambda is a small anonymous function written as a single expression, such as lambda x: x * 2. It's handy for short functions you pass as arguments, like a sort key:

students.sort(key=lambda s: s["marks"], reverse=True)

A lambda can only contain one expression, with no statements, so anything longer belongs in a normal named function defined with def.

13.How does exception handling work in Python?

Code that might fail goes in try. except handles specific exceptions, else runs only if nothing went wrong, and finally always runs, for clean-up:

try:
    value = int(user_input)
except ValueError:
    print("Please enter a number")
else:
    print("Got", value)
finally:
    print("Done")

Catch specific exceptions rather than using a bare except:, and use raise to signal errors in your own code. For files and connections, prefer a with block, which closes the resource even when an error occurs.

14.What are __init__ and self?

__init__ is the initialiser: it runs right after an object is created, to set up its attributes. self is the first parameter of every instance method, and it refers to the object the method was called on:

class Student:
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks

    def passed(self):
        return self.marks >= 40

self isn't a keyword — it's a very strong convention. The object itself is created by __new__, which you rarely need to touch.

15.What is the difference between a module and a package? What does if __name__ == "__main__" do?

A module is a single .py file. A package is a folder of modules — traditionally with an __init__.py file — that you import with dotted names, such as myapp.utils.

When you run a file directly, Python sets its __name__ to "__main__"; when the file is imported, __name__ is the module's name. So code under if __name__ == "__main__": runs only when the file is executed directly — useful for a command-line entry point or quick tests that shouldn't run on import.

16.What is the difference between append() and extend()?

append(x) adds x to the end as a single element; extend(iterable) adds each element of the iterable. With a = [1, 2], a.append([3, 4]) gives [1, 2, [3, 4]], while a.extend([3, 4]) gives [1, 2, 3, 4].

Prepare with Interview Fury

Rehearse these answers out loud with real-time AI help, tailored to your resume and the job description. Free minutes every day — no card required.

Try it free
Try it right now

Click a question. Watch your answer appear.

This is how it looks in a live interview — except there, the question arrives through your call audio, you press a key (or turn on auto-answer), and the answer is written from your resume.

Sample answers, written from a sample resume (Priya, frontend developer, 3 years). In your session, every answer is built from your resume and the job you're interviewing for.

Interview Fury

Pick a question to see how Interview Fury answers it — word by word, as it’s written.

Try it for real — freeNo credit card needed.