1. What is list comprehension?
List comprehension is a concise and readable way to create lists in Python using a single line of code.  It allows you to generate a new list by applying an expression to each item in an iterable, optionally with a condition.

Basic Syntax

Python
[expression for item in iterable] 

Example (Without List Comprehension)

Python
squares = [] for i in range(5): squares.append(i * i) 

Same Using List Comprehension

Python
squares = [i * i for i in range(5)]

Key Advantages

  • Shorter and cleaner code

  • Better readability

  • Faster than traditional loops (in many cases)


2. What is dictionary comprehension?
Dictionary comprehension is a concise and readable way to create dictionaries in Python using a single line of code. It allows you to generate key–value pairs by applying an expression to items in an iterable, optionally with a condition.

Basic Syntax

Python
{key_expression : value_expression for item in iterable} 

Example (Without Dictionary Comprehension)

Python
squares = {} for i in range(5): squares[i] = i * i 

Same Using Dictionary Comprehension

Python
squares = {i: i * i for i in range(5)}

Key Advantages

  • Cleaner and more readable code

  • Less boilerplate than loops

  • Efficient and Pythonic


3. Is tuple comprehension possible?
No, tuple comprehension is NOT possible in Python.

Why Tuple Comprehension Does Not Exist

In Python:

  • List comprehension → creates a list

  • Set comprehension → creates a set

  • Dictionary comprehension → creates a dictionary

  • Tuple comprehension → does not exist

This is because parentheses () are already used for generator expressions.

4. What are *args and **kwargs?

*args and **kwargs are used in Python functions to accept a variable number of arguments, making functions more flexible and reusable.

  • *args → Handles variable-length positional arguments

  • **kwargs → Handles variable-length keyword arguments

*args (Non-keyword Arguments)

What it does

  • Allows a function to accept any number of positional arguments

  • Arguments are received as a tuple

**kwargs (Keyword Arguments)

What it does

  • Allows a function to accept any number of keyword arguments

  • Arguments are received as a dictionary


5. What are lambda functions?
Lambda functions in Python are small, anonymous functions defined using the lambda keyword. They are used to write short, single-expression functions without formally defining a function using def.

Basic Syntax

Python
lambda arguments : expression 
  • No function name

  • Expression is evaluated and returned automatically

  • Can have any number of arguments, but only one expression


Lambda FunctionNormal Function
AnonymousHas a name
Single expressionMultiple statements
One-lineMulti-line
No return keywordUses return

6. When should you use lambda functions?

You should use lambda functions when you need a small, simple, one-time function for a short operation, especially when passing a function as an argument to another function.

Lambda functions are best used where defining a full function using def would be unnecessary or verbose.

Short, Simple Operations

When the logic fits in one expression.

Python
square = lambda x: x * x

Common with map(), filter(), sorted().

Python
nums = [1, 2, 3, 4] evens = list(filter(lambda x: x % 2 == 0, nums))

7. What are first-class functions?

In Python, functions are first-class citizens (first-class functions).
This means functions are treated like any other object, such as integers, strings, or lists.

Because of this, functions in Python can be:

  • Assigned to variables

  • Passed as arguments to other functions

  • Returned from functions

  • Stored in data structures

Key Properties of First-Class Functions

1. Functions Can Be Assigned to Variables

Python
def greet(): return "Hello" say_hello = greet print(say_hello()) 

2. Functions Can Be Passed as Arguments

Python
def apply(func): return func() def hello(): return "Hi" print(apply(hello)) 

3. Functions Can Be Returned from Other Functions

Python
def outer(): def inner(): return "Inner function" return inner func = outer() print(func()) 

4. Functions Can Be Stored in Data Structures

Python
operations = [len, abs, str] print(operations[0]("Python")) 

Why First-Class Functions Are Important

  • Enable higher-order functions

  • Foundation for decorators

  • Support functional programming

  • Make code more modular and reusable


8. Can a function be passed as an argument?

Yes, in Python a function can be passed as an argument to another function.

This is possible because functions in Python are first-class objects, meaning they can be treated like variables and values.

How It Works

  • A function can be passed by its name (without parentheses)

  • The receiving function can call the passed function inside its body

Simple Example

Python
def greet(): return "Hello" def execute(func): return func() print(execute(greet)) 
9. What are iterators?

An iterator in Python is an object that allows you to traverse through a sequence of elements one at a time.
It keeps track of the current position and returns the next value on demand.

Iterators follow the iterator protocol, which means they implement:

  • __iter__()

  • __next__()

How Iterators Work (Step-by-Step)

  1. Convert an iterable into an iterator using iter()

  2. Fetch elements using next()

  3. When elements are exhausted, StopIteration is raised

10. What are generators?

Generators are a special type of function in Python that produce values one at a time using the yield keyword instead of returning them all at once.
They allow lazy evaluation, meaning values are generated only when needed.

How Generators Work

  • Defined like normal functions, but use yield

  • Each yield pauses the function’s execution

  • The function resumes from where it left off on the next call

  • Automatically follow the iterator protocol


Python
def count_up(n): for i in range(1, n + 1): yield i gen = count_up(3) print(next(gen)) # 1 print(next(gen)) # 2 print(next(gen)) # 3
11. What is the difference between an iterator and a generator?

Iterator

What it is

An iterator is an object that:

  • Implements __iter__() (returns itself)

  • Implements __next__() (returns next value)

Example (Custom Iterator)

Python
class Count: def __init__(self, max): self.num = 0 self.max = max def __iter__(self): return self def __next__(self): if self.num < self.max: self.num += 1 return self.num else: raise StopIteration

Characteristics

  • More code required

  • Manual state handling

  • More control over iteration logic

Generator

What it is

A generator is a function that:

  • Uses the yield keyword

  • Automatically implements iterator behavior

Example (Generator)

Python
def count(max): for i in range(1, max + 1): yield i

Characteristics

  • Less code

  • Automatic state management

  • Cleaner and more readable

12. What is exception handling?

Exception handling in Python is a mechanism used to handle runtime errors (exceptions) so that the normal flow of the program is not interrupted.
Instead of crashing the program, Python allows you to catch errors and handle them gracefully.

What is an Exception?

An exception is an error that occurs during program execution.

Examples:

  • Division by zero

  • Accessing an invalid index

  • Converting an invalid string to int

x = 10 / 0 # ZeroDivisionError

Why Exception Handling Is Needed

  • Prevents program crash

  • Improves program reliability

  • Allows meaningful error messages

  • Helps in debugging

Exception Handling Syntax

Python
try: # Code that may cause an exception except ExceptionType: # Code to handle exception else: # Executes if no exception occurs finally: # Always executes
13. How does try-except-else-finally work?
The try–except–else–finally block in Python is used for structured exception handling.  It allows you to separate normal logic, error handling, success logic, and cleanup code clearly.

Execution Flow (Step by Step)

1. try block

  • Python executes this first

  • If an exception occurs → control jumps to except

  • If no exception → except is skipped

2. except block

  • Executes only if an exception occurs in try

  • Handles the error gracefully

  • Prevents program crash

3. else block

  • Executes only if try runs successfully

  • Runs after try and before finally

  • Used for success-related logic

 4. finally block

  • Executes no matter what

    • Python
      import os  

      os.remove("data.txt")Exception occurs or not

  • Used for cleanup operations


14. How do you raise custom exceptions?

In Python, you can create and raise custom exceptions by:

  1. Creating a new class that inherits from Exception

  2. Using the raise keyword to trigger it

This allows you to define application-specific error types for better clarity and control.

Why Use Custom Exceptions?

  • Makes code more readable

  • Separates business logic errors

  • Easier debugging

  • Better error classification


15. What is file handling in Python?
File handling in Python refers to the process of creating, reading, writing, appending, and managing files on the system.  It allows programs to store data permanently instead of keeping it only in memory.

Why File Handling is Important

  • Store application data

  • Log information

  • Read configuration files

  • Process large datasets


Basic Steps in File Handling

  1. Open the file

  2. Perform operations (read/write)

  • Close the file

16. How do you read and write files?
In Python, files are read and written using the open() function, appropriate file modes, and usually the with statement for safe handling.

Open File in Read Mode ("r")

Python
with open("data.txt", "r") as file: content = file.read() print(content)

"r" → Read mode (default)
with automatically closes the file


Writing Files

Write Mode ("w")

Python
with open("data.txt", "w") as file: file.write("Hello Python")

17. How do you delete a file using Python?
In Python, a file can be deleted using the os module or the pathlib module.

Using os.remove() :
Python
import os
os.remove("data.txt")


18. What is the with statement?

The with statement in Python is used to handle resources safely and automatically, such as files, database connections, or network sockets. It ensures that resources are properly acquired and released, even if an error occurs.

Without withWith with
Manual cleanupAutomatic cleanup
Risk of leaksSafe handling
More codeCleaner code


19. What is pickling and unpickling?

Pickling is the process of converting a Python object into a byte stream (serialization) so that it can be stored in a file or transferred over a network.

Unpickling is the reverse process — it converts the byte stream back into the original Python object (deserialization).

Why Pickling is Used

  • Save Python objects permanently

  • Transfer objects across networks

  • Store machine learning models

  • Cache data


PickleJSON
Python-specificLanguage-independent
Binary formatText format
Can serialize complex objectsLimited to basic types
Not human-readableHuman-readable

20. What is shallow copy?

A shallow copy creates a new object, but it does not create copies of nested (inner) objects.
Instead, it copies references to the inner objects.

This means:

  • The outer object is new

  • The inner objects are shared between the original and copied object

When to Use Shallow Copy

  • When object does not contain nested mutable objects

  • When shared inner data is acceptable

  • When performance matters

21. What is deep copy?

A deep copy creates a completely independent copy of an object, including all nested (inner) objects.

This means:

  • The outer object is new

  • All inner objects are also newly created

  • Changes in the copied object do not affect the original object

When to Use Deep Copy

  • When objects contain nested mutable structures

  • When full independence is required

  • When modifying copied object should not affect original


22. What is the difference between shallow and deep copy?
FeatureShallow CopyDeep Copy
Outer object copiedYesYes
Inner objects copied No Yes
Shared referencesYesNo
Independent copyPartialComplete
PerformanceFasterSlower
Memory usageLessMore
Methodcopy.copy()copy.deepcopy()
23. Which sorting algorithm is used by sort() and sorted()?
Both list.sort() and sorted() in Python use the Timsort algorithm.

What is Timsort?

Timsort is a hybrid sorting algorithm derived from:

  • Merge Sort

  • Insertion Sort

It was designed by Tim Peters specifically for Python.

Why Python Uses Timsort

  • Very efficient for real-world data

  • Performs well on partially sorted arrays

  • Stable sorting algorithm

  • Optimized for performance

Key Characteristics of Timsort

FeatureDescription
TypeHybrid (Merge + Insertion)
StabilityStable (maintains order of equal elements)
Time Complexity (Best)O(n)
Time Complexity (Average)O(n log n)
Time Complexity (Worst)O(n log n)
Space ComplexityO(n)


24. How do you debug a Python program?
Debugging is the process of identifying, analyzing, and fixing errors (bugs) in a program. In Python, debugging can be done using multiple techniques depending on the complexity of the issue.

1. Using print() Statements

2. Using Python Debugger (pdb)
3. Using IDE Debuggers
4. Using Logging


25. What is help() and dir()?

help() and dir() are built-in Python functions used for introspection, meaning they help you explore objects, modules, and functions in Python.


help() Function

Purpose:

Displays the documentation (docstring) of a module, function, class, or object.

Example:

Python
help (len) 

Output:

  • Shows description of the len() function

  • Explains parameters and usage

You can also use:

Python
help(list) help("".split)

dir() Function

Purpose:

Returns a list of attributes and methods of an object.

Example:

Python
dir(list)

Output:

  • Shows all methods available for lists
    (append, pop, sort, etc.)


26. What is a module?
A module in Python is simply a file containing Python code (functions, variables, classes, or statements) that can be imported and reused in another
program.

Why Modules Are Important

  • Improve code organization

  • Promote reusability

  • Reduce code duplication

  • Support modular programming


27. What is a package?

A package in Python is a directory (folder) that contains multiple modules and possibly sub-packages.
It helps in organizing related modules into a structured hierarchy.

Why Packages Are Needed

  • Organize large projects

  • Avoid naming conflicts

  • Improve modularity

  • Support scalable applications

28. What is unit testing?
Unit testing is a software testing technique where individual units or components of a program (usually functions or methods) are tested independently to ensure they work correctly.

What is a “Unit”?

A unit is the smallest testable part of an application, such as:

  • A function

  • A method

  • A class

Why Unit Testing is Important

  • Detects bugs early

  • Improves code quality

  • Makes refactoring safer

  • Supports continuous integration

  • Provides documentation of behavior


29. What are global, protected, and private variables?

Global Variables

Definition:

A global variable is defined outside all functions and classes and can be accessed throughout the program.

Python
x = 10 # Global variable def display(): print(x) display()

 Accessible everywhere
 Use global keyword to modify inside functions

Protected Variables

Definition:

A variable with a single underscore _var is considered protected by convention.

Python
class Student: def __init__(self): self._age = 20 # Protected variable

 Intended for internal use
 Can still be accessed outside class
 Used mainly in inheritance

Example:

Python
obj = Student() print(obj._age)

Protected is a convention, not enforced.

Private Variables

Definition:

A variable with double underscore __var is considered private.

Python
class Student: def __init__(self): self._salary = 5000

 Uses name mangling
 Cannot be accessed directly outside the class

TypeSyntaxAccessibilityEnforced?
Globalx = 10Entire programYes (scope-based)
Protected_varInside class & subclassesNo (convention)
Private__varInside class onlyPartial (name mangling)

30. What is polymorphism?
Polymorphism is an Object-Oriented Programming (OOP) concept that means “many forms.” It allows the same method name or function to behave differently depending on the object or context.


31. What is inheritance?
Inheritance is an Object-Oriented Programming (OOP) concept where a child class (derived class) acquires the properties and methods of a parent class (base class).

Why Inheritance is Important

  • Promotes code reusability

  • Reduces duplication

  • Supports hierarchical relationships

  • Improves maintainability

Types of Inheritance in Python

Single Inheritance
Multiple Inheritance
Multilevel Inheritance
Hierarchical Inheritance
Hybrid Inheritance

32. Does Python support multiple inheritance?

Yes, Python fully supports multiple inheritance.

Multiple inheritance means a class can inherit from more than one parent class.

Why Multiple Inheritance is Useful

  • Code reusability

  • Combines behaviors from multiple classes

  • Supports mixin design pattern

33. What is encapsulation?
Encapsulation is an Object-Oriented Programming (OOP) concept that means wrapping data (variables) and methods (functions) together inside a class and restricting direct access to some components.

Why Encapsulation is Important

  • Protects sensitive data

  • Prevents accidental modification

  • Improves security

  • Makes code modular and maintainable

How Encapsulation Works in Python

Python uses:

  • Public variablesvar

  • Protected variables_var

  • Private variables__var


34. What is data abstraction?
Data Abstraction is an Object-Oriented Programming (OOP) principle that focuses on hiding the internal implementation details and showing only the essential features of an object.

Why Abstraction is Important

  • Reduces complexity

  • Improves code security

  • Enhances maintainability

  • Encourages modular design


35. What is the super() function?

The super() function in Python is used to call a method from the parent (base) class inside a child (derived) class.

It is commonly used in inheritance to:

  • Access parent class methods

  • Call parent constructors

  • Support method overriding

Why super() is Important

  • Avoids repeating parent class name

  • Supports multiple inheritance properly

  • Works according to Python’s MRO (Method Resolution Order)

  • Keeps code clean and maintainable

36. How do you copy an object in Python?

In Python, objects can be copied in three main ways:

  1. Assignment (Reference Copy)

  2. Shallow Copy

  3. Deep Copy

The correct method depends on whether the object contains nested mutable elements.


MethodCopies Outer ObjectCopies Inner ObjectsIndependent
Assignment No No No
Shallow Copy Yes NoPartial
Deep Copy Yes YesFully
37. What is memory management in Python?

Memory management in Python refers to how Python allocates, manages, and releases memory automatically during program execution.

Python handles memory internally using:

  • Private Heap Space

  • Reference Counting

  • Garbage Collection

Private Heap Space

  • All Python objects and data structures are stored in a private heap

  • Managed internally by Python’s memory manager

  • Not directly accessible by the programmer

Reference Counting 

Python tracks how many references point to an object.

When the reference count becomes zero, the object is automatically deleted.

Garbage Collection 

Reference counting alone cannot handle circular references.

Example:

Python
a = [] b = [] a.append(b) b.append(a)

Here:

  • Reference count never becomes zero

  • Python’s Garbage Collector (GC) detects and removes such cycles

Python uses a generational garbage collection system.

38. What is reference counting?

Reference counting is the primary memory management technique used by Python to track how many references (variables) are pointing to an object. When the reference count of an object becomes zero, Python automatically deletes the object and frees the memory.

How It Works: The Mechanism :

Each Python object internally maintains a counter (its "reference count") which is automatically managed by the interpreter.

Incrementing the count: The reference count increases when a new reference to the object is created. This happens in several scenarios:

  • Variable assignment: x = object sets the count to at least 1.
  • Aliasing: y = x makes y an additional reference to the same object, increasing the count.
  • Storing in a container: Adding an object to a list, dictionary, or tuple increases its count.
  • Function calls: Passing an object as an argument to a function creates a temporary reference, increasing the count while the function is active.

Decrementing the count: The reference count decreases when a reference to the object is removed or goes out of scope. This occurs when:

  • del statement: del x explicitly removes the variable name, decreasing the count.
  • Reassignment: x = new_object makes x stop referencing the old object, decreasing the old object's count.
  • Going out of scope: Local variables are automatically removed when the function they are in finishes executing, decreasing their objects' counts.
  • Removing from a container: Removing an object from a list (e.g., using list.remove()) decreases its count.

Deallocation: As soon as an object's reference count reaches zero, it means the object is no longer accessible from any part of the program, and Python's memory manager immediately deallocates its memory.

39. What is garbage collection?

Garbage collection (GC) in Python is a memory management mechanism that automatically frees memory occupied by unused objects, especially those involved in circular references.

While Python primarily uses reference counting, garbage collection acts as a secondary mechanism to handle situations where reference counting fails.

Why Garbage Collection is Needed

Reference counting cannot handle circular references.

Python’s garbage collector detects and removes such cycles.

40. What is slicing with step values?
In Python, slicing allows you to extract a portion of a sequence (like a list, tuple, or string).
When you include a step value, it specifies the interval between elements in the slice.

General Syntax

sequence[start : end : step]
  • start → Starting index (inclusive)

  • end → Ending index (exclusive)

  • step → Number of positions to move each time


41. How do you remove duplicates from a list?
There are multiple ways to remove duplicates from a list in Python.
1. set( )
2. dict.fromkeys( )
3. Using Loop

MethodPreserves OrderTime ComplexityRecommended
set() NoO(n)Yes (if order not important)
dict.fromkeys() YesO(n) Best
Loop YesO(n²)Not for large data
42. How do you reverse a string?
There are multiple ways to reverse a string in Python.
The most common and Pythonic way is using slicing with a negative step.

1. Using Slicing
2. Using reverse( ) function
3. Using Loop
4. Using recursion

MethodRecommendedPerformanceReadability
Slicing YesO(n)Excellent
reversed()YesO(n)Good
LoopNoO(n²) (in worst case)Medium
RecursionNoSlowerComplex
43. How do you sort a list of objects by attribute?

To sort a list of objects by a specific attribute, you use:

  • sorted() function

  • list.sort() method

  • The key parameter

  • Usually with lambda or operator.attrgetter

Featuresorted()sort()
Returns new list Yes No
Modifies original No Yes
Works on any iterable Yes Only lists
SpeedSlightly slowerSlightly faster
44. What are virtual environments?
A virtual environment is an isolated Python environment that allows you to install packages and dependencies separately for each project, without affecting the global Python installation.

Why Virtual Environments Are Needed

Suppose:

  • Project A requires Django 3.2

  • Project B requires Django 4.0

Without virtual environments → Version conflict 
With virtual environments → Each project has its own dependencies 

How Virtual Environments Work

Each virtual environment contains:

  • Its own Python interpreter

  • Its own site-packages directory

  • Independent installed libraries

It isolates dependencies from the global environment.

45. How do you install third-party libraries?
Third-party libraries in Python are installed using pip, the official Python package manager.

Basic Installation Using pip

pip install package_name

Example:

pip install requests

46. 
What is the purpose of __str__() and __repr__()?

__str__() and __repr__() are special (magic/dunder) methods in Python used to define how an object is represented as a string.

They control how objects are displayed when:

  • Printed

  • Logged

  • Inspected in console


__str__() → User-Friendly Representation

  • Used by print()

  • Meant for end-users

  • Should be readable and clean


__repr__() → Developer-Friendly Representation

  • Used in interactive shell

  • Used by repr()

  • Should be unambiguous

  • Ideally, should recreate the object