🎯 07 – Interview Questions: Python Basics¶
These are real questions asked in Data Science and Python developer interviews.
🔢 Variables & Data Types¶
Q1: What is the difference between is and == in Python?
Show answer
== compares values; is compares identity (same object in memory).
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True (same values)
print(a is b) # False (different objects)
c = a # c points to the same object
print(a is c) # True
Rule: Use is only for None, True, False comparisons. Use == for value comparisons.
Q2: What is the output of 0.1 + 0.2 == 0.3? Why?
Show answer
False. Floating point numbers can't be represented exactly in binary. Use abs(0.1 + 0.2 - 0.3) < 1e-9 to compare floats.
Q3: What is the difference between int and float? When does division return a float?
Show answer
int stores whole numbers; float stores decimals. In Python 3, / always returns a float (even 4 / 2 = 2.0). Use // for integer division.
🔀 Control Flow¶
Q4: What is the difference between break and continue?
Show answer
break exits the loop entirely. continue skips the rest of the current iteration and jumps to the next one.
Q5: What does this code print?
Show answer
2 — the loop variable i retains its last value after the loop ends, even with pass.
Q6: What is a list comprehension? Write one that filters and transforms.
Show answer
A compact syntax for building lists. Example: get squares of even numbers from 1–20:
🔧 Functions¶
Q7: What is the difference between *args and **kwargs?
Show answer
*argscollects extra positional arguments into a tuple**kwargscollects extra keyword arguments into a dict
Q8: What is a lambda function? Write one that sorts a list of tuples by the second element.
Show answer
An anonymous one-line function.
Q9: What is a mutable default argument trap?
Show answer
Using a mutable object (list, dict) as a default parameter is a classic bug:
📚 Data Structures¶
Q10: What is the difference between a list and a tuple?
Show answer
| List | Tuple | |
|---|---|---|
| Mutable | ✅ | ❌ |
| Syntax | [1,2,3] |
(1,2,3) |
| Use case | Dynamic data | Fixed data, dict keys |
| Speed | Slightly slower | Slightly faster |
Q11: How do you safely get a value from a dict that might not have the key?
Show answer
Use .get() with a default:
Q12: What is the time complexity of in for a list vs a set?
Show answer
List: O(n) — must check every element. Set: O(1) — uses a hash table. For large membership tests, always use a set.
Q13: How do you remove duplicates from a list while preserving order?
Show answer
Q14: What is the difference between append() and extend()?
Show answer
🧰 Advanced Python¶
Q15: What does Python's with statement do? Give a real example.
Show answer
The with statement is a context manager — it guarantees cleanup runs even if an exception occurs inside the block. The object must implement __enter__ and __exit__.
# Without with: file might stay open if read() raises
f = open('data.csv')
content = f.read()
f.close()
# With with: file is always closed, even on error
with open('data.csv') as f:
content = f.read()
# f is closed here automatically
This pattern applies beyond files — database connections, locks, and temporary directories all use context managers.
Q16: What is a generator? How does it differ from a list?
Show answer
A generator yields values one at a time using yield instead of building the whole sequence in memory. It is lazy — each value is computed only when requested.
# List: all 1 million squares stored in memory at once
squares_list = [i**2 for i in range(1_000_000)]
# Generator: computes one value at a time
def squares(n):
for i in range(n):
yield i**2
gen = squares(1_000_000)
print(next(gen)) # 0
print(next(gen)) # 1
Use generators when the sequence is large and you only need one value at a time — for example, streaming rows from a large CSV file.
Q17: What is the difference between deepcopy and a regular assignment in Python?
Show answer
Assignment creates another reference to the same object. Modifying one modifies both. deepcopy creates a fully independent copy — nested structures are copied recursively.
import copy
original = [[1, 2], [3, 4]]
# Assignment — same object
ref = original
ref[0][0] = 99
print(original) # [[99, 2], [3, 4]] ← original changed!
# Deepcopy — independent copy
original = [[1, 2], [3, 4]]
clone = copy.deepcopy(original)
clone[0][0] = 99
print(original) # [[1, 2], [3, 4]] ← original unchanged
This matters for nested structures like lists of lists, dictionaries of lists, or any mutable container inside another.
Q18: Explain the GIL. Why does it matter for data science?
Show answer
The Global Interpreter Lock (GIL) is a mutex in CPython that allows only one thread to execute Python bytecode at a time. This means multi-threaded Python programs cannot run pure Python code in parallel across CPU cores.
# CPU-bound: threads don't help — use multiprocessing
from multiprocessing import Pool
def train_fold(fold_data):
# train a model on this fold
...
with Pool(processes=4) as pool:
results = pool.map(train_fold, folds)
# I/O-bound: threads still help (GIL is released while waiting)
import threading
def download(url):
# network wait releases GIL
...
Key rules for data science:
- Model training (CPU-bound) — use multiprocessing or joblib
- Downloading datasets / API calls (I/O-bound) — threads are fine
- NumPy and Pandas release the GIL for C-level operations, so parallelism works there