Python Interview Questions for Freshers – Expert Guide 2026

JOIN OUR WHATSAPP GROUP

Python Interview Questions for Freshers

1. Basic Python Concepts

Q1. What is Python and why is it popular?ย Python is a high-level, interpreted, general-purpose programming language known for its clean, readable syntax and vast standard library. It is popular because it reduces development time significantly, supports multiple programming paradigms (procedural, OOP, functional), and has one of the largest ecosystems of third-party libraries – making it the go-to language for web development, data science, automation, AI/ML, and scripting.


Q2. What is the difference between interpreted and compiled languages? Where does Python fit? A compiled language (like C or C++) converts the entire source code to machine code before execution. An interpreted language executes code line by line at runtime. Python is interpreted – the Python interpreter reads and executes code directly without a separate compilation step, which makes development faster but generally slower at runtime than compiled languages.


Q3. What are Python’s key features?

  • Dynamically typed – variable types are determined at runtime
  • Strongly typed – implicit type conversion is not allowed between incompatible types
  • Interpreted – executed line by line
  • Object-oriented – supports classes and inheritance
  • Multi-paradigm – supports OOP, functional, and procedural styles
  • Garbage collected – automatic memory management
  • Cross-platform – runs on Windows, Linux, macOS without modification

Q4. What is PEP 8? PEP 8 is Python’s official style guide – a set of conventions for writing readable Python code. Key rules include 4-space indentation (not tabs), maximum line length of 79 characters, two blank lines before and after class/function definitions, lowercase with underscores for variable and function names (snake_case), and CamelCase for class names. Following PEP 8 is expected in professional Python codebases.


Q5. What is the difference between is and == in Python? == checks value equality – whether two objects have the same value. is checks identity – whether two variables point to the exact same object in memory.

python

a = [1, 2, 3]
b = [1, 2, 3]
print(a == b)   # True  - same values
print(a is b)   # False - different objects in memory

c = a
print(a is c)   # True  - same object

Use is only for comparing to None (if x is None), not for general value comparison.


2. Data Types and Data Structures

Q6. What are Python’s built-in data types?

CategoryTypes
Numericint, float, complex
Textstr
Sequencelist, tuple, range
Mappingdict
Setset, frozenset
Booleanbool
Binarybytes, bytearray
NoneNoneType

Q7. What is the difference between a list, tuple, and set?

FeatureListTupleSet
MutableYesNoYes
OrderedYesYesNo
DuplicatesYesYesNo
Syntax[1,2,3](1,2,3){1,2,3}

Use lists when you need a mutable ordered collection. Use tuples for fixed data that should not change (coordinates, RGB values). Use sets when you need uniqueness or fast membership testing.


Q8. What is a dictionary and when would you use it? A dictionary is an unordered (Python 3.7+ maintains insertion order) collection of key-value pairs. Keys must be unique and hashable. Dictionaries offer O(1) average-time lookup by key – making them ideal for any situation where you need to map one piece of data to another (e.g., a user profile, configuration settings, frequency counting).

python

student = {"name": "Ravi", "age": 22, "score": 91.5}
print(student["name"])   # Ravi
student["city"] = "Hyderabad"  # Add new key

Q9. What is the difference between deepcopy and shallow copy? A shallow copy creates a new object but copies references to the objects inside it – so nested mutable objects are shared between the original and the copy. A deep copycreates a completely independent copy – all nested objects are also copied recursively.

python

import copy
original = [[1, 2], [3, 4]]

shallow = copy.copy(original)
deep = copy.deepcopy(original)

original[0][0] = 99
print(shallow[0][0])  # 99 - affected by change
print(deep[0][0])     # 1  - completely independent

Q10. How do you remove duplicates from a list while preserving order?

python

# Method 1 - Using dict.fromkeys (Python 3.7+, preserves order)
lst = [3, 1, 2, 1, 3, 4]
result = list(dict.fromkeys(lst))
print(result)  # [3, 1, 2, 4]

# Method 2 - Manual loop
seen = set()
result = []
for item in lst:
    if item not in seen:
        result.append(item)
        seen.add(item)

3. Functions

**Q11. What are *args and kwargs? *args allows a function to accept any number of positional arguments as a tuple. **kwargs allows a function to accept any number of keyword arguments as a dictionary.

python

def show(*args, **kwargs):
    print(args)   # ('a', 'b', 'c')
    print(kwargs) # {'x': 1, 'y': 2}

show('a', 'b', 'c', x=1, y=2)

Q12. What is a lambda function? A lambda is an anonymous, single-expression function defined inline. It is useful for short throwaway functions, especially as arguments to map()filter(), or sorted().

python

square = lambda x: x ** 2
print(square(5))  # 25

numbers = [3, 1, 4, 1, 5, 9]
print(sorted(numbers, reverse=True))  # [9, 5, 4, 3, 1, 1]

# Lambda with sorted key
people = [("Ravi", 25), ("Priya", 22), ("Arun", 28)]
sorted_people = sorted(people, key=lambda x: x[1])

Q13. What is the difference between map()filter(), and reduce()?

  • map(func, iterable) – applies func to every element and returns a map object
  • filter(func, iterable) – returns elements for which func returns True
  • reduce(func, iterable) – cumulatively applies func to reduce the iterable to a single value (requires from functools import reduce)

python

nums = [1, 2, 3, 4, 5]

squared = list(map(lambda x: x**2, nums))        # [1, 4, 9, 16, 25]
evens   = list(filter(lambda x: x%2==0, nums))   # [2, 4]

from functools import reduce
total = reduce(lambda x, y: x+y, nums)           # 15

Q14. What is a decorator in Python? A decorator is a function that takes another function as input, adds behaviour to it, and returns the modified function – without changing the original function’s code. Decorators use the @ syntax and are widely used for logging, authentication, timing, and caching.

python

def log_call(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}")
        result = func(*args, **kwargs)
        print(f"Done {func.__name__}")
        return result
    return wrapper

@log_call
def greet(name):
    print(f"Hello, {name}!")

greet("Ravi")
# Calling greet
# Hello, Ravi!
# Done greet

Q15. What is a generator and how is it different from a regular function? A generator is a function that uses yieldinstead of return. It does not compute all values at once – it produces values one at a time, only when requested (lazy evaluation). This makes generators memory-efficient for large sequences.

python

def count_up(n):
    for i in range(n):
        yield i

gen = count_up(1000000)
print(next(gen))  # 0 - only one value computed at a time
print(next(gen))  # 1

A regular function with return computes the full result and stores it in memory. A generator produces values on demand.


4. Object-Oriented Programming

Q16. What are the four pillars of OOP in Python?

  • Encapsulation – bundling data and methods together inside a class, and restricting direct access to internal state using private/protected attributes
  • Inheritance – a child class inherits attributes and methods from a parent class, enabling code reuse
  • Polymorphism – the same method name behaves differently depending on the object it is called on
  • Abstraction – hiding internal implementation details and exposing only what is necessary

Q17. What is the difference between __init__ and __new__? __new__ creates the instance (allocates memory). __init__initialises it (sets attributes). In virtually all standard Python code, you only override __init____new__ is rarely overridden except when subclassing immutable types like int or str, or implementing singleton patterns.

python

class Dog:
    def __init__(self, name, breed):
        self.name = name
        self.breed = breed

    def bark(self):
        return f"{self.name} says: Woof!"

dog = Dog("Tommy", "Labrador")
print(dog.bark())  # Tommy says: Woof!

Q18. What are @classmethod and @staticmethod?

python

class Counter:
    count = 0

    def __init__(self):
        Counter.count += 1

    @classmethod
    def get_count(cls):
        # Receives the class as first argument (cls)
        # Can access and modify class state
        return cls.count

    @staticmethod
    def description():
        # Receives no implicit first argument
        # Cannot access class or instance state
        return "This class counts instances"

Counter()
Counter()
print(Counter.get_count())    # 2
print(Counter.description())  # This class counts instances

Use @classmethod when the method needs to access or modify class-level state. Use @staticmethod for utility functions that logically belong to the class but do not depend on class or instance data.


Q19. What is method resolution order (MRO) in Python? MRO determines the order in which Python searches for methods in a class hierarchy – especially relevant in multiple inheritance. Python uses the C3 linearisation algorithm. You can view it with ClassName.__mro__ or ClassName.mro().

python

class A:
    def method(self): print("A")

class B(A):
    def method(self): print("B")

class C(A):
    def method(self): print("C")

class D(B, C):
    pass

D().method()     # B - follows MRO: D โ†’ B โ†’ C โ†’ A
print(D.__mro__) # (<class 'D'>, <class 'B'>, <class 'C'>, <class 'A'>, <class 'object'>)

5. Error Handling and File I/O

Q20. How does Python handle exceptions?

python

try:
    result = 10 / 0
except ZeroDivisionError as e:
    print(f"Error: {e}")
except (ValueError, TypeError) as e:
    print(f"Value/Type error: {e}")
else:
    # Runs only if no exception was raised
    print(f"Result: {result}")
finally:
    # Always runs - for cleanup
    print("Execution complete")

Always catch specific exceptions rather than using a bare except: – catching all exceptions silently hides bugs.


Q21. What is the difference between raise and raise from? raise re-raises an exception or raises a new one. raise ... from ...chains exceptions – it explicitly links a new exception to the original one, preserving the full error context in the traceback.

python

try:
    int("abc")
except ValueError as e:
    raise RuntimeError("Conversion failed") from e

Q22. How do you read and write files in Python?

python

# Writing a file
with open("data.txt", "w") as f:
    f.write("Hello, Python!\n")
    f.write("Line 2")

# Reading entire file
with open("data.txt", "r") as f:
    content = f.read()

# Reading line by line (memory efficient)
with open("data.txt", "r") as f:
    for line in f:
        print(line.strip())

Always use the with statement for file operations – it ensures the file is properly closed even if an exception occurs.


6. Python Internals

Q23. What is a mutable vs immutable type in Python? Immutable types cannot be changed after creation – intfloatstrtuplefrozensetMutable types can be modified in place – listdictset. This distinction matters when passing objects to functions – mutable objects are passed by reference and modifications inside the function affect the original.

python

# Immutable - original unchanged
def add_one(n):
    n += 1

x = 5
add_one(x)
print(x)  # Still 5

# Mutable - original changed
def append_item(lst):
    lst.append(99)

nums = [1, 2, 3]
append_item(nums)
print(nums)  # [1, 2, 3, 99]

Q24. What are list comprehensions and when should you use them? List comprehensions provide a concise, readable way to create lists from existing iterables – often replacing 3-4 lines of loop code with a single expressive line. They are generally faster than equivalent for-loops because they are optimised at the C level.

python

# Traditional
squares = []
for x in range(10):
    if x % 2 == 0:
        squares.append(x**2)

# List comprehension - same result, one line
squares = [x**2 for x in range(10) if x % 2 == 0]
# [0, 4, 16, 36, 64]

# Dict comprehension
word_lengths = {word: len(word) for word in ["Python", "Java", "Go"]}
# {'Python': 6, 'Java': 4, 'Go': 2}

Q25. What is the Global Interpreter Lock (GIL)? The GIL is a mutex in CPython (the standard Python interpreter) that allows only one thread to execute Python bytecode at a time – even on multi-core systems. This means Python threads do not achieve true parallel execution for CPU-bound tasks. For CPU-bound work, use multiprocessing (separate processes bypass the GIL). For I/O-bound work (network calls, file reads), multithreading works fine because threads release the GIL while waiting for I/O.


7. Common Coding Questions

Q26. How do you reverse a string in Python?

python

s = "Python"
print(s[::-1])       # nohtyP  - slicing (fastest, most Pythonic)
print("".join(reversed(s)))  # nohtyP  - using reversed()

Q27. How do you check if a string is a palindrome?

python

def is_palindrome(s):
    s = s.lower().replace(" ", "")
    return s == s[::-1]

print(is_palindrome("racecar"))   # True
print(is_palindrome("A man a plan a canal Panama"))  # True
print(is_palindrome("python"))    # False

Q28. How do you find the most frequent element in a list?

python

from collections import Counter

nums = [1, 3, 2, 1, 4, 1, 3, 2, 1]
c = Counter(nums)
print(c.most_common(1)[0][0])  # 1

# Manual approach
print(max(nums, key=nums.count))  # 1

Q29. How do you merge two dictionaries in Python 3.9+?

python

a = {"x": 1, "y": 2}
b = {"y": 99, "z": 3}

# Python 3.9+ - merge operator
merged = a | b
print(merged)  # {'x': 1, 'y': 99, 'z': 3}

# Python 3.5+ - unpacking
merged = {**a, **b}

# In-place update
a.update(b)

When keys overlap, the right-hand dictionary’s value wins.


Q30. What is the time complexity of common Python operations?

OperationListDictSet
Access by indexO(1)
SearchO(n)O(1) avgO(1) avg
Insert at endO(1) amortizedO(1) avgO(1) avg
Insert at startO(n)
DeleteO(n)O(1) avgO(1) avg
Membership testO(n)O(1) avgO(1) avg

Are you looking for Job Opportunities

๐Ÿ‘‰ Check latest Internships

๐Ÿ‘‰ Check latest IT Jobs

Leave a Comment