Python Full-Stack Interview Questions 6–10 (Memory, Namespaces, Copies, Iterators, Comprehensions)
In this lesson, we continue strengthening your Python foundations with concepts that often feel abstract at first but become essential as you work in real projects. These topics help you understand how Python manages memory, organizes variables, controls iteration, and provides elegant shortcuts for writing cleaner code. Our goal here is to make each topic feel natural and understandable, without rushing or overwhelming.
6. Explain Python's garbage collection mechanism.
Python manages memory automatically, meaning you do not manually allocate or free memory (like in languages such as C). The main idea is that Python keeps track of how many references point to an object. When no references remain, the object is considered no longer needed and can safely be removed from memory. This is known as reference counting.
However, sometimes two objects can reference each other in a cycle, making their reference counts never reach zero. To handle such situations, Python also runs a garbage collector that detects and clears these circular references.
- Reference counting: Every object tracks how many references point to it.
- Garbage collector: Detects unused objects, especially from circular references, and frees memory.
Think of it like keeping items in your house. If something is still being used (referenced), it stays. Once there is nothing using it anymore, the garbage collector acts like a cleanup crew removing clutter.
import gc
# Check if garbage collector is enabled
print(gc.isenabled())
# Manually trigger garbage collection
gc.collect()7. What are Python namespaces?
A namespace in Python is like a container that holds names and their corresponding objects. Whenever you create a variable, a function, or a class, the name you assign is stored inside a namespace. Namespaces help avoid naming conflicts and allow the same name to be used in different contexts without interfering with each other.
- Local Namespace: Names defined inside a function.
- Global Namespace: Names defined at the top level of a script or module.
- Built-in Namespace: Names that Python provides by default (like
lenorprint).
Imagine namespaces as labeled boxes in a shelf. You can have the same item name in different boxes without confusion. Python checks namespaces in a specific order when searching for a name: Local → Global → Built-in. This is called the LEGB rule.
x = "global value"
def sample():
x = "local value"
print(x)
sample() # prints: local value
print(x) # prints: global value8. Difference between shallow copy and deep copy.
When copying collections like lists or dictionaries, it’s important to know whether you are copying just the references or the actual data. A shallow copy creates a new container but keeps references to the same elements inside. A deep copy creates a completely independent copy, including nested elements.
- Shallow Copy: Copies the top-level container only.
- Deep Copy: Copies the container and all nested objects.
Imagine copying a bookshelf. Shallow copy is like building the same shelf structure but using the same books. Deep copy means building the shelf and making new physical copies of every book.
import copy
original = [[1, 2], [3, 4]]
shallow = copy.copy(original)
deep = copy.deepcopy(original)
original[0][0] = 99
print(shallow) # [[99, 2], [3, 4]] shares nested lists
print(deep) # [[1, 2], [3, 4]] independent copy9. What are Python iterators and generators?
Iterators provide a way to loop through data one element at a time. Any object that implements the __iter__() and __next__() methods is considered an iterator. Generators are a simpler and more memory-efficient way to create iterators using the yield keyword.
Generators are especially helpful when dealing with large datasets because they produce values one at a time instead of storing everything in memory.
def count_up_to(n):
i = 1
while i <= n:
yield i
i += 1
for num in count_up_to(5):
print(num)10. What are Python comprehensions?
Comprehensions provide a concise and expressive way to create lists, sets, and dictionaries. They allow you to transform or filter data in a clean, readable format. Instead of writing multiple lines of loops and conditionals, comprehensions let you accomplish the same work in a single meaningful expression.
- List Comprehension
- Set Comprehension
- Dictionary Comprehension
numbers = [1, 2, 3, 4, 5]
# List comprehension
squares = [n*n for n in numbers]
# Dictionary comprehension
mapping = {n: n*n for n in numbers}
print(squares) # [1, 4, 9, 16, 25]
print(mapping) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}Comprehensions help make your code more readable, intentional, and expressive. They express not just what you want to do, but why you are doing it: transforming data into a new form.