Python Interview Questions Guide
Python Interview Questions Guide
Complete
Preparation Book for
Python
[Link]
Python
Python
Concept Introduction:
Python has become one of the most widely used programming
languages in the world, powering everything from web applications
and data science to machine learning and automation. Its simplicity,
versatility, and “batteries included” philosophy make it a favorite
among developers as well as companies like Google, Amazon,
Microsoft, Infosys, and TCS.
This sheet is a carefully curated collection of 50 handpicked Python
interview questions that are most commonly asked in coding
interviews, placement drives, and technical assessments. The
questions are designed to test not only your coding ability but also your
understanding of Python’s core concepts, internals, and real-world
problem-solving skills.
Some of these questions have been actually asked in top tech
companies, while others are highly relevant and expected in interviews.
Together, they cover everything from Python basics and OOP to
advanced topics like multithreading, decorators, generators, and
performance optimization.
If you go through these questions thoroughly, practice coding, and
understand the explanations, you’ll be well-prepared to tackle Python
rounds in placements, internships, and job interviews.
Q1. What are Python’s key features? Why is it called “batteries included”? (TCS)
Explanation:
1
Python
• Large standard library → built-in modules for file I/O, regex, math, networking,
JSON, databases, etc.
• Extensible and integrable → can integrate with C/C++, Java, or call APIs.
The phrase “batteries included” means Python comes with a very rich standard
library—you don’t need to install extra packages for many common tasks like
handling files, JSON, XML, math, databases, or HTTP. This saves time and effort.
Answer:
It’s called ‘batteries included’ because its standard library already covers a wide
range of tasks—like file handling, networking, and data processing—without
needing external packages.
Explanation:
Python 2 (released 2000) and Python 3 (released 2008) are two major versions.
Python 2 is now deprecated (support ended in 2020), while Python 3 is the present
and future.
Key differences:
2. Integer division → In Python 2, 5/2 = 2; in Python 3, 5/2 = 2.5 (true division). Use
// for floor division.
2
Python
Because of these differences, Python 2 code often doesn’t run directly on Python 3
without modification.
Answer:
Python 2 is old and no longer supported, while Python 3 is the current standard.
Main differences: print is a function in Python 3, division gives float by default,
strings are Unicode by default, range() works like xrange(), and exception syntax
changed to as. Most libraries now support only Python 3.
Explanation:
Python uses namespaces to avoid naming conflicts. For example, if two functions
have variables with the same name, their namespaces keep them separate.
So, when you use a variable, Python checks in this order until it finds it.
Answer:
Python has built-in, global, enclosing, and local namespaces, and it resolves names
using the LEGB rule—Local → Enclosing → Global → Built-in.
3
Python
Explanation:
o All Python objects and data structures are stored in a private heap.
o The Python interpreter manages this heap; you can’t access it directly.
Extra points:
• del keyword reduces the reference count of an object but doesn’t always
delete immediately if references still exist.
• Memory efficiency can also be improved using tools like __slots__ in classes.
Answer:
Python uses a private heap for storing objects, managed by the interpreter.
It uses reference counting for automatic garbage collection, and a cyclic garbage
collector handles circular references.
Developers can also use the gc module for fine control, but in most cases memory
is managed automatically.
Explanation:
• Python Lists:
4
Python
o They are heterogeneous → can store different data types in the same list
([1, "hello", 3.5]).
o Because of this, lists are flexible but take more memory and are slower
for numerical computations.
• C Arrays:
o They are homogeneous → all elements must be of the same data type
(e.g., int arr[5]).
So, Python lists are powerful and flexible, while C arrays are low-level, memory-
efficient, and type-restricted.
Answer:
Python lists are dynamic and can hold mixed data types, internally storing
references to objects.
C arrays are static, fixed in size, and store only one type in contiguous memory,
making them more memory-efficient but less flexible.
Q6. What are Python’s mutable and immutable data types? (Accenture)
Explanation:
Answer:
In Python, mutable objects are those that can be modified after creation, like lists,
dictionaries, sets, and bytearrays.
For example, in a list, I can change an element, append new elements, or remove
existing ones without creating a new object.
On the other hand, immutable objects cannot be changed once created. These
include integers, floats, strings, tuples, frozensets, and bytes. If I try to modify them,
Python actually creates a new object in memory.
For example, changing a string creates a new string rather than modifying the
original.
This difference is important because immutable objects are hashable, so they can
be used as dictionary keys or set elements, while mutable ones cannot. In short,
mutables offer flexibility, whereas immutables provide stability and are safer in
situations where fixed values are required.
Explanation:
3. gc Module → Developers can interact with the garbage collector (e.g., disable,
enable, or manually trigger collection).
Answer:
However, since reference counting alone can’t handle circular references, Python
also uses a cyclic garbage collector that works in generations to find and clean
them. If needed, developers can control this behavior using the gc module.
Explanation:
== (Equality Operator):
• Uses the object’s __eq__() method to check if contents are the same.
is (Identity Operator):
7
Python
Answer:
In Python, == checks for value equality, meaning whether the contents of two
objects are the same.
On the other hand, is checks for identity—whether both variables refer to the exact
same object in memory.
For example, two lists with the same elements will be equal with ==, but not
identical with is. A common use of is is checking against None, while == is used for
comparing values.
Explanation:
The Global Interpreter Lock (GIL) is a mutex (lock) used in CPython (the default
Python implementation).
It ensures that only one thread executes Python bytecode at a time, even on multi-
core processors.
Impact:
2. I/O-bound tasks (e.g., file operations, network requests): Threads still work
well because Python releases the GIL during blocking I/O, allowing
concurrency.
Answer:
The Global Interpreter Lock, or GIL, is a mutex in CPython that allows only one
thread to execute Python bytecode at a time. It makes memory management
simpler but prevents true parallel execution of CPU-bound threads.
That’s why threading in Python is best for I/O-bound tasks, while multiprocessing
is preferred for CPU-heavy tasks.
Explanation:
8
Python
• When you insert a key, Python computes its hash value (using __hash__()),
then maps it to an index in the table.
• Sometimes, two different keys may produce the same hash index → this is
called a collision.
• If the target index is already occupied, Python looks for the next available slot
in the table (linear probing).
• During lookup, it checks the hash and then the actual key (using __eq__) to
ensure correctness.
• If the table gets too full, Python automatically resizes (rehashes) to reduce
collisions.
Answer:
Python dictionaries are hash tables. When two keys hash to the same index, a
collision occurs.
Python resolves this using open addressing with probing—it searches for the next
free slot and stores the item there.
During lookups, it checks both the hash and the key for correctness. If the table
gets too full, it resizes to keep performance close to O(1).
Explanation:
• When an element is added, Python computes its hash value and places it in
a slot based on that hash.
• Because the position depends on the hash, and because the hash table can
resize dynamically when it grows, the order of elements is not preserved.
• This is why sets appear “unordered” and why their iteration order can change
between runs or after modifications.
9
Python
• The main goal of sets is fast membership testing (O(1) average time), not
maintaining order.
(Note: From Python 3.7+, dictionaries preserve insertion order, but sets still do not
guarantee it. In practice, you may see some order, but it’s not reliable or part of the
specification.)
Answer:
Python sets are unordered because they are implemented as hash tables.
The position of each element depends on its hash value and may change when the
table resizes, so order is not guaranteed. Sets are designed for fast membership
checks, not for maintaining order.
Explanation:
o In Python, we can use append() to push and pop() to remove the last
element.
o Note: pop(0) is not very efficient (O(n)), so for real queues we use
[Link]. But in interviews, list-based implementation is fine.
10
# Pop
print("Popped element:", [Link]())
print("Stack after pop:", stack)
# Enqueue
[Link](10)
[Link](20)
[Link](30)
print("Queue after enqueues:", queue)
# Dequeue
print("Dequeued element:", [Link](0))
print("Queue after dequeue:", queue)
Output :
11
Python
Answer:
A stack can be implemented using a Python list with append() for push and pop()
for pop, since lists allow fast operations at the end.
A queue can also be implemented using a list, with append() for enqueue and
pop(0) for dequeue, though for efficiency [Link] is usually preferred.
Q13. How does Python’s dict maintain insertion order? (Python 3.7+) (Microsoft)
Explanation:
• Python 3.7+: It was officially made part of the language specification that dict
will always maintain the order of key insertion.
• Along with the hash table, Python maintains a compact array of insertion
order.
• This array keeps track of the sequence in which keys are inserted, ensuring
iteration happens in that order.
• When you delete a key, its slot in the order array is marked as deleted, but
the insertion order of the remaining items is preserved.
This makes operations like iteration predictable and consistent, which is useful in
modern Python programming.
Answer:
Internally, a dict uses a hash table for fast lookups and an additional compact array
that records the order in which keys were inserted.
This allows iteration over a dictionary to return elements in the order they were
added. If a key is deleted, the order of the remaining elements remains unchanged.
12
Python
Explanation:
A priority queue is like a normal queue, but instead of being processed in the order
items arrive (FIFO), elements are processed based on their priority (higher priority
first).
2. Using [Link]:
o You could push items into a list and sort each time, but that’s inefficient
(O(n log n)) compared to heaps.
Answer:
In Python, a priority queue can be implemented using the heapq module, which
provides an efficient min-heap data structure. We use heappush() to insert
elements and heappop() to remove the element with the highest priority (smallest
value).
For example:
13
Python
Explanation:
o Example:
o Example:
14
Python
When combined:
You can use both in a function, but the order must be:
Answer:
For example:
Explanation:
A decorator in Python is a special function that allows you to modify or extend the
behavior of another function without changing its actual code.
Functions in Python are first-class objects, meaning they can be passed around as
arguments, returned from other functions, and stored in variables.
A decorator typically:
• Code reusability.
15
Python
Basic Example:
Here:
• The wrapper function adds behavior before and after the original function.
Answer:
They are widely used for logging, authentication, and performance measurement.
Explanation:
• Take self as the first argument, which refers to the object instance.
16
Python
• Can access and modify both object attributes and class attributes.
• Example:
• Take cls as the first argument, which refers to the class itself (not an object).
• Example:
• Behave like normal functions inside the class (placed there for logical
grouping).
• Example:
17
Python
Key Differences:
• Static Method: Just a function inside a class; neither class nor object data is
passed automatically.
Answer:
In Python, instance methods take self and are used to access or modify object data.
Class methods use @classmethod, take cls, and are meant for class-level data
shared across all objects.
Static methods use @staticmethod, don’t take self or cls, and are just utility
functions placed inside a class for logical grouping.
Explanation:
In Python, Method Resolution Order (MRO) defines the sequence in which classes
are searched when calling a method or attribute.
• The search goes from left to right in the inheritance list, but it also respects
the order of parent classes.
Example:
18
Python
Answer:
MRO in Python is the order in which classes are searched when resolving a method
or attribute.
Explanation:
Duck typing is a concept in Python (and other dynamically typed languages) where
the type or class of an object is less important than the methods and properties it
has.
“If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is
a duck.”
In Python:
Example:
19
Python
Here, make_it_quack() doesn’t care whether the object is Duck or Person. As long
as it has a .quack() method, it works.
Answer:
Duck typing in Python means that instead of checking an object’s type, we focus
on whether it has the required methods or attributes.
If an object behaves like the expected type, it can be used, regardless of its actual
class. For example, if two classes both have a quack() method, they can be used
interchangeably, even if they are different types.
Explanation:
Multiple Inheritance means a class can inherit from more than one base class.
Example:
The problem:
When two parent classes have the same method, which one should Python call?
If B and C both override a method from A, and D inherits from both, should D call
B’s version, C’s version, or both?
• MRO defines the exact order in which classes are searched when calling a
method.
Rules of MRO:
Answer:
In Python, multiple inheritance allows a class to inherit from more than one parent.
21
Python
The main challenge is the diamond problem, where the same method might exist
in multiple parent classes. Python handles this using the Method Resolution Order
(MRO), based on the C3 linearization algorithm.
MRO defines a consistent order of searching: left to right in the inheritance list,
ensuring each parent is called only once, and respecting the hierarchy.
For example, if a class D inherits from B and C, which both inherit from A, the MRO
might be [D, B, C, A, object]. This ensures there’s no ambiguity in method calls.
Explanation:
It can contain:
class Animal(ABC):
@abstractmethod
def sound(self):
pass
class Dog(Animal):
22
Python
def sound(self):
return "Bark"
class Cat(Animal):
def sound(self):
return "Meow"
Here:
Answer:
Abstract classes can have abstract methods (without implementation) which must
be implemented by all subclasses, along with normal methods.
They are mainly used to enforce a common interface and ensure consistency across
different subclasses.
Explanation:
In Python, both __str__ and __repr__ are special methods that return a string
representation of an object. But their purposes are different:
23
Python
o Goal → Return a readable and nicely formatted string for end users.
o Meant to be human-readable.
Answer:
Explanation:
24
Python
A data class in Python is a class that is mainly used to store data rather than
behavior.
Normally, when you create a class to store data, you have to write a lot of boilerplate
code — __init__, __repr__, __eq__, etc.
For example:
This is repetitive.
Answer:
In Python, data classes are classes decorated with @dataclass from the dataclasses
module, introduced in Python 3.7.
They are mainly used to store data and automatically generate common methods
like __init__, __repr__, and __eq__, which reduces boilerplate code.
They also support type hints, default values, and custom methods if needed.
Q24. Difference between finally, else, and with statements in exception handling.
Explanation:
25
Python
In Python exception handling (try…except), we can also use finally, else, and with —
but each serves a different purpose:
1. finally block
o Guarantees cleanup.
2. else block
o Useful for code that should only execute when the try succeeds.
o Not exactly part of try-except, but often used with exception handling.
26
Python
Answer:
with is not part of try-except but works as a context manager to handle resources
safely, ensuring automatic setup and cleanup without needing an explicit finally.
Explanation:
Exceptions in Python are errors that disrupt the normal flow of a program. While
Python has many built-in exceptions (ValueError, TypeError, etc.), sometimes we
need our own exception type to make error handling more meaningful.
• Create a new class that inherits from Python’s built-in Exception class (or any
subclass of it).
Why useful?
27
Python
Answer:
In Python, we create custom exceptions by defining a class that inherits from the
built-in Exception class.
We then raise it using the raise keyword and handle it in a try-except block. This is
useful when we want more meaningful, application-specific error messages.
Q26. Explain the use of with open() for file handling. (TCS)
Explanation:
The problem is — if an exception occurs, the file may remain open, leading to
memory leaks or file locks.
To solve this, Python provides the with statement (context manager). When used
with open(), it:
• Ensures the file is closed automatically once the block ends — even if an error
occurs.
28
Python
So instead of:
Answer:
In Python, with open() is used for file handling because it automatically manages
resources.
It opens the file, allows operations inside the block, and ensures the file is closed
automatically after the block ends, even if an exception occurs.
This makes the code cleaner and safer compared to manually calling close().
Explanation:
When you open a file in Python with open(), the operating system allocates
resources (like file handles, memory buffers, locks) for that file.
1. Resource leakage → The file handle remains occupied, which can cause your
program or system to run out of available file handles if many files are left
open.
2. Data loss → For write operations, data is often stored in a buffer before being
written to disk. If the file isn’t closed, some data may never be flushed (saved)
to the file.
29
Python
3. File locking issues → On some OS (like Windows), the file might stay locked,
preventing other programs or even your own program from
accessing/modifying it.
Answer:
If you don’t close a file in Python, it can lead to resource leaks, unsaved data
(because buffers may not flush), and file locking issues.
Although Python may close the file when the object is garbage-collected, relying
on that is unsafe.
That’s why it’s best practice to always close files, usually by using with open() which
ensures automatic closure.
Explanation:
Both pip and conda are package managers in Python, but they are not the same:
Example:
Example:
30
Python
Key Differences:
Answer:
If you need a package with C dependencies (like NumPy with optimized binaries):
Explanation:
In Python, if you install packages globally, every project shares the same set of
dependencies. This often leads to “dependency conflicts” (different projects
needing different versions of the same library).
2. When you activate the environment, your shell modifies the PATH so that the
python and pip you use point to the ones inside the virtual environment.
3. Any package installed with pip install goes only inside that environment, not
affecting global Python.
Answer:
31
Python
When activated, the environment overrides the system Python path so that python
and pip commands use the isolated environment. This allows different projects to
have their own dependencies without conflicts.
Q30. Difference between Python standard modules os, sys, and subprocess.
Explanation:
1. os module
2. sys module
32
Python
3. subprocess module
Answer:
In Python, os is used to interact with the operating system like file, directory, and
environment operations. sys interacts with the Python interpreter itself, giving
access to arguments, path, and exit functions.
Explanation:
33
Python
In Python, packages are directories that contain multiple modules (files). To tell
Python that a directory should be treated as a package, it traditionally needed an
__init__.py file inside it.
1. Package indicator
o From Python 3.3+, it’s optional (namespace packages exist), but still
widely used for clarity.
2. Initialization code
3. Control imports
o You can define __all__ inside __init__.py to specify what gets imported
when someone does from package import *.
Answer:
It can contain initialization code, import specific modules, or define what gets
exposed when using from package import *. While optional since Python 3.3 (due
to namespace packages), it’s still commonly used for clarity and control.
Explanation:
Iterators
• Example:
34
Python
Iterators can be built manually by creating a class with __iter__ and __next__, but
that’s often verbose.
Generators
• Generators are a simpler way to create iterators using the yield keyword.
• They are lazy — values are generated on the fly, not stored in memory.
• Example:
Key Differences:
1. Creation:
2. Memory efficiency:
o Iterator → may store data in memory (if built from lists, etc.).
3. Ease of use:
Answer:
35
Python
A generator is a simpler way to create iterators using the yield keyword. Generators
are more memory-efficient because they generate values lazily on demand, while
iterators often hold data in memory.
In short, all generators are iterators, but not all iterators are generators.
Explanation:
A closure is a function that remembers the variables from its enclosing scope even
after that scope has finished executing.
3. The outer function returns the inner function, and the inner function still has
access to those outer variables.
Closures are commonly used in decorators, callbacks, and when you want to
“remember” a value without using global variables or classes.
Answer:
A closure in Python is a function that retains access to variables from its enclosing
scope even after the outer function has finished execution.
It allows data to be preserved across function calls without using global variables.
36
Python
Explanation:
• A normal function executes all its code at once and returns a single value
using return.
This allows you to produce a sequence of values lazily (one at a time) instead of
generating and storing everything in memory at once, which is very efficient for
large data or infinite sequences.
Example:
37
Python
Answer:
The yield keyword in Python is used to create generator functions. Unlike return,
which ends the function, yield pauses execution and returns a value, resuming
from the same point on the next call.
This enables lazy evaluation, efficient memory usage, and iteration over large or
infinite sequences.
Explanation:
Context managers are commonly used with the with statement, which ensures
resources are released automatically, even if exceptions occur.
Even if an exception occurs inside the block, the file will still be closed.
38
Python
Answer:
It uses __enter__ and __exit__ methods and is mostly used with the with statement.
For example, with open("[Link]") as f: ensures the file is automatically closed after
use, even if an error occurs.
Explanation:
In Python, however, due to the Global Interpreter Lock (GIL), only one thread can
execute Python bytecode at a time.
So multithreading is useful mostly for I/O-bound tasks (like file handling, network
requests, waiting for user input) where threads spend time waiting and not much
CPU work.
Multiprocessing means running multiple processes. Each process has its own
Python interpreter and memory space.
This bypasses the GIL, so multiple CPU cores can actually be used in parallel.
39
Python
Key differences:
2. Speed – Threads are lightweight; Processes are heavier but give true
parallelism.
3. Use case – Threads for I/O-bound tasks, Processes for CPU-bound tasks.
Answer:
Multiprocessing creates separate processes, each with its own Python interpreter
and memory space, so it achieves true parallelism and is best for CPU-bound tasks.
Multithreading, on the other hand, runs multiple threads within the same process
and shares memory, but due to the GIL only one thread executes Python code at a
time, so it’s better suited for I/O-bound tasks.
Explanation:
Normally, Python code runs synchronously — each line waits for the previous one
to finish. But in cases like web requests, database queries, or reading files, a lot of
time is spent just waiting. That’s where asynchronous programming comes in.
o Inside it, you can use await to pause execution until an awaited task is done
(like waiting for a network call).
o While one coroutine is waiting, Python can run another coroutine, making
the program more efficient.
This doesn’t create new threads or processes. Instead, it uses an event loop (from
the asyncio module) that schedules and switches between tasks.
In short:
• await → pauses the function until the awaited task finishes, without blocking
other tasks.
• Best for I/O-bound tasks (web scraping, APIs, DB calls), not for CPU-heavy
tasks.
40
Python
Answer:
In Python, async and await are used to write asynchronous code with coroutines.
An async def function defines a coroutine, and await pauses its execution until the
awaited task completes.
While one coroutine waits, the event loop can run other coroutines, which makes
async programming very efficient for I/O-bound tasks like network calls or file
operations.
Explanation:
Coroutines are special functions in Python that can pause and resume their
execution, unlike regular functions that run from start to finish.
They are created using async def and executed using an event loop (usually from
the asyncio module).
Key points:
41
Python
Answer:
Coroutines are Python functions defined with async def that can pause execution
with await and resume later.
They allow concurrent execution of I/O-bound tasks within a single thread, making
asynchronous programming efficient without using multiple threads or processes.
Explanation:
Integers:
• Python integers are objects of the int class. Internally, they are stored as
objects, not as raw C integers.
• Small integers (usually -5 to 256) are interned, meaning Python reuses the
same object to save memory.
Strings:
1. Reference count
2. Type pointer
• Python may intern small strings (like identifiers or short literals) to save
memory, meaning identical strings can share the same memory.
42
Python
Key idea: everything in Python is an object, so even integers and strings are stored
as objects with metadata, not raw primitive types like in C.
Answer:
An integer object contains its value, reference count, and type info, with small
integers (-5 to 256) being interned for memory efficiency.
Strings are immutable objects stored as sequences of Unicode code points along
with metadata like reference count, type, and length, and short strings may also be
interned to save memory.
Explanation:
2. Any new reference to the same string will reuse the existing object, instead
of creating a new one.
This helps reduce memory usage and makes string comparisons faster (because
comparing object references is faster than comparing character by character).
• Short strings
You can also manually intern strings using [Link]() if you want to enforce it.
Answer:
43
Python
Explanation:
Python is an interpreted language, while Java and C++ are compiled languages.
This means Python code is executed line by line, whereas C++/Java code is
compiled into machine code or bytecode, which runs faster.
Answer:
Explanation:
A memory leak occurs when a program keeps allocating memory but never
releases it, causing the program to use more and more memory over time.
Python’s garbage collector can handle circular references, but developers still need
to manage memory carefully in long-running applications.
44
Python
Tools like gc module, tracemalloc, or memory profilers can help detect and fix leaks.
Answer:
A memory leak in Python occurs when objects are no longer needed but are not
released, causing increased memory usage.
Python’s garbage collector handles most cases, but developers need to manage
memory carefully in long-running applications.
Explanation:
In Python, every object is normally kept alive as long as there’s at least one
reference pointing to it. These are called strong references.
But sometimes, you might want to refer to an object without preventing Python
from cleaning it up when it’s no longer needed. That’s where weak references come
in.
A weak reference allows you to reference an object without increasing its reference
count, so it doesn’t block garbage collection.
This is very useful in scenarios like caches, object registries, or tracking objects
where you don’t want your references to unintentionally keep objects in memory.
Python provides the weakref module for creating weak references. If the object is
deleted, the weak reference becomes None or can trigger a callback function,
allowing you to safely handle the cleanup.
Essentially, weak references let you keep tabs on objects without interfering with
Python’s memory management, reducing the risk of memory leaks.
Answer:
In Python, a weak reference is a reference to an object that does not increase its
reference count.
This means the object can still be garbage collected when no strong references
exist.
Weak references are useful for cases like caches or tracking objects, where you
want to access objects if they exist but don’t want to prevent Python from freeing
memory when they are no longer needed.
45
Python
They can be created using the weakref module, and optionally, you can attach a
callback to handle object cleanup. Using weak references helps manage memory
efficiently and prevents unintentional memory retention.
Explanation:
Optimizing Python code involves improving speed, memory usage, and efficiency.
Python is high-level and easy to write, but sometimes naive code can be slow.
1. Use built-in functions and libraries: Python’s built-ins (like sum(), min(), max())
and standard libraries (itertools, collections) are implemented in C, so they
are much faster than custom Python loops.
2. Choose the right data structures: Use lists, sets, dictionaries, and tuples
appropriately. For example, membership checks in sets/dictionaries are
faster than lists.
4. Lazy evaluation: Use generators (yield) to process large data without loading
everything into memory.
5. Profile and identify bottlenecks: Use cProfile or timeit to find slow parts and
focus optimization there.
Answer:
To optimize Python code performance, you should first profile your code to identify
bottlenecks using tools like cProfile or timeit.
Then, use built-in functions and libraries for efficiency, choose appropriate data
structures (sets/dictionaries for fast lookups), avoid unnecessary loops by using list
comprehensions or generators, and reuse objects to reduce overhead.
For large or I/O-bound tasks, use asyncio or multithreading, and for CPU-bound
tasks, consider multiprocessing. Efficient memory and object management,
46
Python
combined with targeted optimization after profiling, ensures both speed and
maintainable code.
Q45. What are Python’s built-in optimization techniques like lru_cache? (Google)
Explanation:
lru_cache stands for Least Recently Used cache: it stores the results of expensive
function calls so that future calls with the same arguments return instantly from
the cache instead of recomputing.
This is particularly useful for recursive functions like Fibonacci, where the same
computation happens multiple times.
Answer:
These tools allow Python programs to run faster and use memory more effectively
without major code changes.
Q46. What is the difference between deepcopy() and shallow copy in Python?
(Asked in Accenture)
47
Python
Explanation:
In Python, when you copy objects, there are two common approaches: shallow
copy and deep copy. A shallow copy means a new object is created, but the nested
objects inside it are still references to the original. So if you modify a nested element
in the copied object, it also changes in the original. This is done using the
[Link]() method.
On the other hand, a deep copy creates a completely independent copy of the
object, including all nested objects. Any change in the copied object will not affect
the original. This is achieved using [Link]().
This difference is very important when working with nested lists, dictionaries, or
custom objects, because a shallow copy can sometimes lead to bugs when both
the original and copied objects unintentionally share data.
Answer:
A shallow copy (using [Link]()) creates a new object but keeps references to
nested objects, so changes in nested elements affect both.
For example, copying a nested list with shallow copy still links inner lists, while
deepcopy duplicates them.
Explanation:
A metaclass is essentially the “class of a class.” Just like a class defines the behavior
of its objects, a metaclass defines the behavior of classes. By default, Python uses
type as the metaclass. That’s why when you check type(MyClass), it returns <class
'type'>.
Answer:
A metaclass in Python is the class that creates classes. By default, Python classes
are created using the type metaclass. Developers can define custom metaclasses
to control class creation, such as modifying attributes or enforcing constraints.
48
Python
While not needed in daily coding, metaclasses are powerful tools used internally
by frameworks like Django to automate behavior.
Q48. How does Python handle function overloading since it doesn’t support it
directly? (Asked in Infosys)
Explanation:
Unlike Java or C++, Python does not allow multiple functions with the same name
but different parameters. If you define a function again, the new one simply
replaces the old.
3. Manual handling inside the function → You can check argument types and
counts, then implement behavior accordingly.
Answer:
A single function can thus accept different numbers or types of arguments and
handle them conditionally.
For example, a function add(a, b=0) can be called with one or two arguments,
behaving like two different versions.
Explanation:
For example, if a library function has a bug or doesn’t behave as expected, you can
redefine it in your own code without altering the library files. While this is powerful,
it should be used carefully because it can make code harder to understand and
maintain.
49
Python
Answer:
For example, you can override a method in a built-in class or third-party library
without touching its source. While useful for quick fixes or testing, it is risky
because it may lead to unpredictable behavior and maintenance challenges.
Q50. Explain Python’s slots and why they are used. (Asked in Amazon)
Explanation:
The __slots__ mechanism allows you to explicitly declare fixed attributes for a class.
By doing this, Python does not create a __dict__ for each instance, which saves
memory and improves access speed.
However, the trade-off is that you cannot add new attributes dynamically outside
of those declared in __slots__. This makes classes less flexible but more efficient.
Answer:
__slots__ in Python are used to define a fixed set of attributes in a class, preventing
the creation of a per-instance dictionary. This reduces memory usage and speeds
up attribute access, which is especially beneficial when creating millions of objects.
The limitation is that you can’t add new attributes beyond those defined in
__slots__.
50
Thank You
For Reading !
Success doesn’t come from
what you do occasionally, it
comes from what you do
consistently.
CREATED BY - TOPPERWORLD
[Link]