Top 50 Python Interview Questions with Answers
Master the most frequently asked Python interview questions and ace your next technical interview
Introduction
Python has become one of the most popular programming languages in the world, widely used in web development, data science, machine learning, automation, and more. Whether you're preparing for a job interview at a tech company or a startup, mastering Python fundamentals is essential.
This comprehensive guide covers the 50 most frequently asked Python interview questions, organized by topic for easy navigation. Each question includes a detailed answer with code examples where applicable.
Python Basics (Q1-Q10)
Q1. What is Python? What are its key features?
Answer: Python is a high-level, interpreted, and general-purpose programming language. Key features:
- Simple and Readable: Clean syntax, easy to learn
- Interpreted: No compilation needed, runs directly
- Dynamically Typed: No need to declare variable types
- Object-Oriented: Supports OOP concepts
- Extensive Libraries: Rich standard library and third-party packages
- Cross-platform: Runs on Windows, Linux, macOS
- Open Source: Free to use and modify
Q2. What is the difference between Python 2 and Python 3?
Answer: Key differences:
| Python 2 | Python 3 |
|---|---|
| print is a statement | print() is a function |
| Integer division returns int | Integer division returns float |
| Unicode strings need 'u' prefix | Strings are Unicode by default |
| xrange() for iteration | range() returns iterator |
| raw_input() for input | input() returns string |
# Python 2
print "Hello" # Statement
5 / 2 # Returns 2
# Python 3
print("Hello") # Function
5 / 2 # Returns 2.5
5 // 2 # Returns 2 (integer division)
Q3. What are Python's built-in data types?
Answer: Python has several built-in data types:
- Numbers: int, float, complex
- Sequences: str, list, tuple, range
- Mappings: dict
- Sets: set, frozenset
- Booleans: bool (True/False)
- None: NoneType
# Numbers
x = 10 # int
y = 3.14 # float
z = 2 + 3j # complex
# Sequences
name = "Python" # str
numbers = [1, 2, 3] # list
coordinates = (4, 5) # tuple
r = range(5) # range
# Mapping
person = {"name": "John", "age": 30} # dict
# Sets
unique = {1, 2, 3} # set
frozen = frozenset([1, 2, 3]) # frozenset
# Boolean
is_active = True # bool
# None
value = None # NoneType
Q4. What is the difference between list and tuple?
Answer:
| List | Tuple |
|---|---|
| Mutable (can be modified) | Immutable (cannot be modified) |
| Defined with square brackets [] | Defined with parentheses () |
| More memory consumption | Less memory consumption |
| Slower iteration | Faster iteration |
| Methods: append(), extend(), remove() | No methods to modify |
# List - Mutable
my_list = [1, 2, 3]
my_list.append(4) # [1, 2, 3, 4]
my_list[0] = 10 # [10, 2, 3, 4]
# Tuple - Immutable
my_tuple = (1, 2, 3)
# my_tuple[0] = 10 # Error! Cannot modify tuple
# my_tuple.append(4) # Error! No append method
Q5. What is PEP 8?
Answer: PEP 8 is Python's official style guide. It provides conventions for writing readable Python code.
Key PEP 8 Guidelines:
- Use 4 spaces for indentation (not tabs)
- Maximum line length: 79 characters
- Use blank lines to separate functions and classes
- Use snake_case for function and variable names
- Use PascalCase for class names
- Use UPPER_CASE for constants
- Import statements should be at the top
# Good PEP 8 style
def calculate_total(items):
"""Calculate total price of items."""
total = 0
for item in items:
total += item.price
return total
class ShoppingCart:
MAX_ITEMS = 100 # Constant
def __init__(self):
self.items = []
Q6. What is the difference between == and is in Python?
Answer:
- == (Equality): Compares the values of two objects
- is (Identity): Compares if two variables point to the same object in memory
# == compares values
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True (same values)
# is compares identity (memory location)
print(a is b) # False (different objects)
# is returns True only if same object
c = a
print(a is c) # True (same object)
# Special case: Small integers are cached
x = 256
y = 256
print(x is y) # True (cached)
x = 257
y = 257
print(x is y) # False (not cached)
Q7. What are Python decorators?
Answer: Decorators are functions that modify the behavior of other functions without changing their code. They use the @ symbol.
# Simple decorator
def my_decorator(func):
def wrapper():
print("Something before function")
func()
print("Something after function")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# Output:
# Something before function
# Hello!
# Something after function
# Decorator with arguments
def repeat(times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello, {name}!")
greet("Python") # Prints 3 times
Q8. What is the difference between deep copy and shallow copy?
Answer:
- Shallow Copy: Creates a new object but references the same nested objects
- Deep Copy: Creates a completely independent copy with its own nested objects
import copy
original = [[1, 2, 3], [4, 5, 6]]
# Shallow copy
shallow = copy.copy(original)
shallow[0][0] = 999
print(original) # [[999, 2, 3], [4, 5, 6]] - Modified!
print(shallow) # [[999, 2, 3], [4, 5, 6]]
# Deep copy
original = [[1, 2, 3], [4, 5, 6]]
deep = copy.deepcopy(original)
deep[0][0] = 999
print(original) # [[1, 2, 3], [4, 5, 6]] - Not modified
print(deep) # [[999, 2, 3], [4, 5, 6]]
Q9. What are Python generators?
Answer: Generators are functions that return an iterator. They use yield instead of return and generate values on-the-fly, saving memory.
# Generator function
def count_up_to(max):
count = 1
while count <= max:
yield count
count += 1
# Using generator
counter = count_up_to(5)
for num in counter:
print(num) # 1, 2, 3, 4, 5
# Generator expression
squares = (x**2 for x in range(5))
for square in squares:
print(square) # 0, 1, 4, 9, 16
# Memory efficient - doesn't store all values
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fib = fibonacci()
for _ in range(10):
print(next(fib)) # 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
Q10. What is the Global Interpreter Lock (GIL)?
Answer: GIL is a mutex that allows only one thread to execute Python bytecode at a time, even on multi-core systems.
Implications:
- Python threads cannot run in parallel for CPU-bound tasks
- GIL is released for I/O operations, so threads work well for I/O-bound tasks
- For CPU-bound parallelism, use multiprocessing instead of threading
# Threading (affected by GIL) - good for I/O-bound
import threading
import time
def io_task():
time.sleep(1) # Simulates I/O operation
# Multiple threads can run concurrently for I/O
threads = [threading.Thread(target=io_task) for _ in range(5)]
for t in threads:
t.start()
for t in threads:
t.join()
# Multiprocessing (bypasses GIL) - good for CPU-bound
import multiprocessing
def cpu_task(n):
return sum(i*i for i in range(n))
# Multiple processes run in parallel
with multiprocessing.Pool() as pool:
results = pool.map(cpu_task, [1000000] * 4)
Data Structures (Q11-Q20)
Q11. What is the difference between list, tuple, set, and dictionary?
Answer:
| Type | Mutable | Ordered | Indexed | Duplicates |
|---|---|---|---|---|
| list | Yes | Yes | Yes | Yes |
| tuple | No | Yes | Yes | Yes |
| set | Yes | No (Python 3.7+) | No | No |
| dict | Yes | Yes (Python 3.7+) | Yes (by key) | No (keys) |
Q12. How do you remove duplicates from a list?
Answer: Multiple ways to remove duplicates:
# Method 1: Using set (loses order in Python < 3.7)
my_list = [1, 2, 2, 3, 4, 4, 5]
unique = list(set(my_list)) # [1, 2, 3, 4, 5]
# Method 2: Using dict.fromkeys() (preserves order)
unique = list(dict.fromkeys(my_list)) # [1, 2, 3, 4, 5]
# Method 3: Using list comprehension with seen set
seen = set()
unique = [x for x in my_list if not (x in seen or seen.add(x))]
# Method 4: Using OrderedDict (Python < 3.7)
from collections import OrderedDict
unique = list(OrderedDict.fromkeys(my_list))
Q13. What is list comprehension? Give examples.
Answer: List comprehension is a concise way to create lists.
# Basic syntax: [expression for item in iterable]
# Example 1: Squares
squares = [x**2 for x in range(5)] # [0, 1, 4, 9, 16]
# Example 2: With condition
evens = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]
# Example 3: Nested
matrix = [[i*j for j in range(3)] for i in range(3)]
# [[0, 0, 0], [0, 1, 2], [0, 2, 4]]
# Example 4: With if-else
result = [x if x > 0 else 0 for x in [-1, 2, -3, 4]] # [0, 2, 0, 4]
# Example 5: Flattening a list
nested = [[1, 2], [3, 4], [5, 6]]
flat = [item for sublist in nested for item in sublist] # [1, 2, 3, 4, 5, 6]
Q14. What is dictionary comprehension?
Answer: Similar to list comprehension but creates dictionaries.
# Basic syntax: {key: value for item in iterable}
# Example 1: Squares dictionary
squares = {x: x**2 for x in range(5)} # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# Example 2: With condition
evens = {x: x*2 for x in range(10) if x % 2 == 0}
# Example 3: From two lists
keys = ['a', 'b', 'c']
values = [1, 2, 3]
mapping = {k: v for k, v in zip(keys, values)} # {'a': 1, 'b': 2, 'c': 3}
# Example 4: Inverting dictionary
original = {'a': 1, 'b': 2, 'c': 3}
inverted = {v: k for k, v in original.items()} # {1: 'a', 2: 'b', 3: 'c'}
Q15. How do you merge two dictionaries in Python?
Answer: Multiple ways to merge dictionaries:
# Method 1: Using ** operator (Python 3.5+)
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
merged = {**dict1, **dict2} # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# Method 2: Using update()
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4} # 'b' will be overwritten
dict1.update(dict2) # dict1 = {'a': 1, 'b': 3, 'c': 4}
# Method 3: Using | operator (Python 3.9+)
merged = dict1 | dict2
# Method 4: Using ChainMap
from collections import ChainMap
merged = dict(ChainMap(dict1, dict2))
Q16. What is the difference between append() and extend()?
Answer:
- append(): Adds a single element to the end of the list
- extend(): Adds all elements from an iterable to the end of the list
# append() - adds the whole object
my_list = [1, 2, 3]
my_list.append([4, 5])
print(my_list) # [1, 2, 3, [4, 5]]
# extend() - adds elements from iterable
my_list = [1, 2, 3]
my_list.extend([4, 5])
print(my_list) # [1, 2, 3, 4, 5]
# extend() with string
my_list = [1, 2]
my_list.extend("abc")
print(my_list) # [1, 2, 'a', 'b', 'c']
Q17. What are *args and **kwargs?
Answer:
- *args: Allows passing variable number of positional arguments (as tuple)
- **kwargs: Allows passing variable number of keyword arguments (as dictionary)
# *args example
def sum_numbers(*args):
return sum(args)
print(sum_numbers(1, 2, 3)) # 6
print(sum_numbers(1, 2, 3, 4, 5)) # 15
# **kwargs example
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="John", age=30, city="NYC")
# Output:
# name: John
# age: 30
# city: NYC
# Combined usage
def my_function(*args, **kwargs):
print("Args:", args)
print("Kwargs:", kwargs)
my_function(1, 2, 3, name="John", age=30)
# Args: (1, 2, 3)
# Kwargs: {'name': 'John', 'age': 30}
Q18. What is the difference between range() and xrange()?
Answer:
- range() (Python 3): Returns a range object (iterator), memory efficient
- xrange() (Python 2): Returns xrange object, memory efficient (removed in Python 3)
- range() (Python 2): Returns a list, memory intensive
# Python 3 - range() returns iterator
r = range(5)
print(list(r)) # [0, 1, 2, 3, 4]
print(type(r)) #
# Memory efficient - doesn't store all values
for i in range(1000000): # Uses constant memory
pass
# Python 2 (deprecated)
# range(5) returns [0, 1, 2, 3, 4] - list
# xrange(5) returns xrange object - iterator
range() works like Python 2's xrange().
Q19. How do you sort a list in Python?
Answer: Multiple ways to sort:
# Method 1: sort() - modifies original list
my_list = [3, 1, 4, 1, 5, 9, 2, 6]
my_list.sort()
print(my_list) # [1, 1, 2, 3, 4, 5, 6, 9]
# Method 2: sorted() - returns new sorted list
my_list = [3, 1, 4, 1, 5, 9, 2, 6]
sorted_list = sorted(my_list)
print(sorted_list) # [1, 1, 2, 3, 4, 5, 6, 9]
print(my_list) # [3, 1, 4, 1, 5, 9, 2, 6] - unchanged
# Reverse sort
my_list.sort(reverse=True) # [9, 6, 5, 4, 3, 2, 1, 1]
# Sort by key
students = [('John', 25), ('Jane', 22), ('Bob', 30)]
students.sort(key=lambda x: x[1]) # Sort by age
# [('Jane', 22), ('John', 25), ('Bob', 30)]
# Sort dictionary by value
my_dict = {'a': 3, 'b': 1, 'c': 2}
sorted_dict = dict(sorted(my_dict.items(), key=lambda x: x[1]))
# {'b': 1, 'c': 2, 'a': 3}
Q20. What is the difference between remove(), pop(), and del?
Answer:
| Method | Usage | Returns |
|---|---|---|
| remove() | Removes first occurrence of value | None |
| pop() | Removes element at index (default: last) | Removed element |
| del | Deletes element(s) by index/slice | None |
# remove() - removes by value
my_list = [1, 2, 3, 2, 4]
my_list.remove(2) # Removes first 2
print(my_list) # [1, 3, 2, 4]
# pop() - removes by index, returns value
my_list = [1, 2, 3, 4]
value = my_list.pop() # Removes last element
print(value) # 4
print(my_list) # [1, 2, 3]
value = my_list.pop(0) # Removes element at index 0
print(value) # 1
print(my_list) # [2, 3]
# del - deletes by index or slice
my_list = [1, 2, 3, 4, 5]
del my_list[0] # Removes element at index 0
print(my_list) # [2, 3, 4, 5]
del my_list[1:3] # Removes slice
print(my_list) # [2, 5]
Object-Oriented Programming (Q21-Q30)
Q21. What is the difference between class and instance variables?
Answer:
- Class Variable: Shared by all instances, defined outside
__init__ - Instance Variable: Unique to each instance, defined in
__init__
class Dog:
# Class variable
species = "Canine"
count = 0
def __init__(self, name):
# Instance variable
self.name = name
Dog.count += 1
dog1 = Dog("Buddy")
dog2 = Dog("Max")
print(dog1.name) # Buddy (instance variable)
print(dog2.name) # Max (instance variable)
print(dog1.species) # Canine (class variable)
print(dog2.species) # Canine (class variable)
print(Dog.count) # 2 (class variable)
Q22. What is __init__ method?
Answer: __init__ is a special method (constructor) that is automatically called when an object is created. It initializes the object's attributes.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
print(f"{name} created")
person = Person("John", 30)
# Output: John created
print(person.name) # John
print(person.age) # 30
Q23. What is the difference between __str__ and __repr__?
Answer:
- __str__: User-friendly string representation (for end users)
- __repr__: Developer-friendly string representation (for debugging, should be unambiguous)
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"Point({self.x}, {self.y})"
def __repr__(self):
return f"Point(x={self.x}, y={self.y})"
p = Point(3, 4)
print(str(p)) # Point(3, 4) - user-friendly
print(repr(p)) # Point(x=3, y=4) - developer-friendly
print(p) # Point(3, 4) - calls __str__
Q24. What is inheritance in Python?
Answer: Inheritance allows a class to inherit attributes and methods from another class.
# Parent class
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "Some sound"
# Child class
class Dog(Animal):
def speak(self):
return f"{self.name} says Woof!"
class Cat(Animal):
def speak(self):
return f"{self.name} says Meow!"
dog = Dog("Buddy")
cat = Cat("Whiskers")
print(dog.speak()) # Buddy says Woof!
print(cat.speak()) # Whiskers says Meow!
Q25. What is method overriding?
Answer: Method overriding occurs when a child class provides a specific implementation of a method that is already defined in the parent class.
class Shape:
def area(self):
return 0
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self): # Overriding parent's area method
return self.width * self.height
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self): # Overriding parent's area method
return 3.14159 * self.radius ** 2
rect = Rectangle(5, 3)
circle = Circle(4)
print(rect.area()) # 15
print(circle.area()) # 50.26544
Q26. What is multiple inheritance?
Answer: Python supports multiple inheritance where a class can inherit from multiple parent classes.
class Flyable:
def fly(self):
return "Flying"
class Swimmable:
def swim(self):
return "Swimming"
class Duck(Flyable, Swimmable):
def quack(self):
return "Quack!"
duck = Duck()
print(duck.fly()) # Flying
print(duck.swim()) # Swimming
print(duck.quack()) # Quack!
# Method Resolution Order (MRO)
print(Duck.__mro__) # Shows inheritance order
Q27. What is the difference between @staticmethod and @classmethod?
Answer:
| @staticmethod | @classmethod |
|---|---|
| No access to class or instance | Receives class as first argument (cls) |
| Cannot modify class state | Can modify class state |
| Called on class or instance | Called on class or instance |
class Math:
pi = 3.14159
@staticmethod
def add(a, b):
return a + b
@classmethod
def get_pi(cls):
return cls.pi
@classmethod
def set_pi(cls, value):
cls.pi = value
# Static method - no access to class/instance
result = Math.add(5, 3) # 8
# Class method - access to class
print(Math.get_pi()) # 3.14159
Math.set_pi(3.14)
print(Math.get_pi()) # 3.14
Q28. What are magic methods (dunder methods)?
Answer: Magic methods are special methods with double underscores (__) that define how objects behave with built-in operations.
class Book:
def __init__(self, title, pages):
self.title = title
self.pages = pages
def __str__(self):
return f"{self.title} ({self.pages} pages)"
def __len__(self):
return self.pages
def __eq__(self, other):
return self.pages == other.pages
def __add__(self, other):
return Book(f"{self.title} & {other.title}",
self.pages + other.pages)
book1 = Book("Python", 300)
book2 = Book("Java", 250)
print(str(book1)) # Python (300 pages)
print(len(book1)) # 300
print(book1 == book2) # False
combined = book1 + book2
print(combined) # Python & Java (550 pages)
Q29. What is encapsulation in Python?
Answer: Encapsulation is the bundling of data and methods. Python uses naming conventions for access control:
- Public: No prefix (default)
- Protected: Single underscore (_)
- Private: Double underscore (__)
class BankAccount:
def __init__(self, balance):
self.balance = balance # Public
self._account_number = "12345" # Protected (convention)
self.__pin = "0000" # Private (name mangling)
def get_balance(self):
return self.balance
def _validate(self): # Protected method
return True
def __verify_pin(self): # Private method
return self.__pin == "0000"
account = BankAccount(1000)
print(account.balance) # 1000 (accessible)
print(account._account_number) # 12345 (accessible but convention)
# print(account.__pin) # Error! Name mangled to _BankAccount__pin
print(account._BankAccount__pin) # 0000 (can access but shouldn't)
Q30. What is polymorphism in Python?
Answer: Polymorphism allows objects of different classes to be treated as objects of a common base class.
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
class Duck(Animal):
def speak(self):
return "Quack!"
# Polymorphism - same interface, different implementations
animals = [Dog(), Cat(), Duck()]
for animal in animals:
print(animal.speak())
# Output:
# Woof!
# Meow!
# Quack!
Advanced Topics (Q31-Q40)
Q31. What is a lambda function?
Answer: Lambda is an anonymous function defined with the lambda keyword. It can have any number of arguments but only one expression.
# Lambda syntax: lambda arguments: expression
# Regular function
def add(x, y):
return x + y
# Lambda equivalent
add_lambda = lambda x, y: x + y
print(add(5, 3)) # 8
print(add_lambda(5, 3)) # 8
# Common use cases
# 1. With map()
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers)) # [1, 4, 9, 16, 25]
# 2. With filter()
evens = list(filter(lambda x: x % 2 == 0, numbers)) # [2, 4]
# 3. With sorted()
students = [('John', 25), ('Jane', 22), ('Bob', 30)]
sorted_students = sorted(students, key=lambda x: x[1]) # Sort by age
Q32. What is the difference between map(), filter(), and reduce()?
Answer:
- map(): Applies function to all items in iterable, returns map object
- filter(): Filters items based on condition, returns filter object
- reduce(): Applies function cumulatively, returns single value (from functools)
from functools import reduce
numbers = [1, 2, 3, 4, 5]
# map() - transform each element
squared = list(map(lambda x: x**2, numbers)) # [1, 4, 9, 16, 25]
# filter() - select elements
evens = list(filter(lambda x: x % 2 == 0, numbers)) # [2, 4]
# reduce() - accumulate to single value
sum_all = reduce(lambda x, y: x + y, numbers) # 15
product = reduce(lambda x, y: x * y, numbers) # 120
Q33. What are Python modules and packages?
Answer:
- Module: A single Python file containing functions, classes, and variables
- Package: A directory containing multiple modules and an
__init__.pyfile
# Module: math_utils.py
def add(a, b):
return a + b
def multiply(a, b):
return a * b
# Using module
import math_utils
result = math_utils.add(5, 3)
# Or
from math_utils import add, multiply
result = add(5, 3)
# Package structure:
# mypackage/
# __init__.py
# module1.py
# module2.py
# Using package
from mypackage import module1
from mypackage.module2 import some_function
Q34. What is the difference between import and from import?
Answer:
# import - imports entire module
import math
result = math.sqrt(16) # 4.0
# from import - imports specific items
from math import sqrt, pi
result = sqrt(16) # 4.0
print(pi) # 3.141592653589793
# from import * - imports all (not recommended)
from math import *
result = sqrt(16) # Can use without math. prefix
# import as - aliasing
import numpy as np
import pandas as pd
from module import function) instead of import * to avoid namespace pollution.
Q35. What is exception handling in Python?
Answer: Exception handling uses try-except blocks to handle errors gracefully.
# Basic exception handling
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero!")
# Multiple exceptions
try:
value = int("abc")
result = 10 / value
except ValueError:
print("Invalid number!")
except ZeroDivisionError:
print("Division by zero!")
# Exception with else and finally
try:
file = open("data.txt", "r")
content = file.read()
except FileNotFoundError:
print("File not found!")
else:
print("File read successfully!")
finally:
print("This always executes")
# file.close() would go here
Q36. What is the difference between finally and else in exception handling?
Answer:
- else: Executes only if no exception occurs
- finally: Always executes, regardless of exceptions
try:
result = 10 / 2
except ZeroDivisionError:
print("Error occurred")
else:
print("No error - else block executes") # This executes
finally:
print("Finally always executes") # This always executes
try:
result = 10 / 0
except ZeroDivisionError:
print("Error occurred") # This executes
else:
print("No error") # This doesn't execute
finally:
print("Finally always executes") # This always executes
Q37. What is the with statement?
Answer: The with statement ensures proper resource management (context management). It automatically handles setup and cleanup.
# File handling with 'with' statement
with open("file.txt", "r") as file:
content = file.read()
# File automatically closed when block exits
# Equivalent to:
file = open("file.txt", "r")
try:
content = file.read()
finally:
file.close()
# Custom context manager
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
with FileManager("data.txt", "w") as f:
f.write("Hello, World!")
Q38. What are Python iterators and iterables?
Answer:
- Iterable: Object that can be iterated over (has
__iter__method) - Iterator: Object that implements
__iter__and__next__methods
# Custom iterator
class CountDown:
def __init__(self, start):
self.current = start
def __iter__(self):
return self
def __next__(self):
if self.current <= 0:
raise StopIteration
self.current -= 1
return self.current + 1
# Using iterator
counter = CountDown(5)
for num in counter:
print(num) # 5, 4, 3, 2, 1
# Using next()
counter = CountDown(3)
print(next(counter)) # 3
print(next(counter)) # 2
print(next(counter)) # 1
Q39. What is the difference between list and generator?
Answer:
| List | Generator |
|---|---|
| Stores all values in memory | Generates values on-the-fly |
| Can access by index | Cannot access by index |
| Can iterate multiple times | Can iterate only once |
| More memory consumption | Memory efficient |
# List - stores all values
my_list = [x**2 for x in range(1000000)] # Uses memory
# Generator - generates on demand
my_gen = (x**2 for x in range(1000000)) # Memory efficient
# List can be accessed multiple times
my_list = [1, 2, 3]
for item in my_list:
print(item) # Works
for item in my_list:
print(item) # Works again
# Generator can be used only once
my_gen = (x for x in range(3))
for item in my_gen:
print(item) # 0, 1, 2
for item in my_gen:
print(item) # Nothing (exhausted)
Q40. What is the difference between threading and multiprocessing?
Answer:
| Threading | Multiprocessing |
|---|---|
| Shares memory space | Separate memory space |
| Affected by GIL | Bypasses GIL |
| Good for I/O-bound tasks | Good for CPU-bound tasks |
| Lightweight | Heavier (more overhead) |
# Threading - I/O bound
import threading
import time
def io_task():
time.sleep(1) # Simulates I/O
threads = [threading.Thread(target=io_task) for _ in range(5)]
for t in threads:
t.start()
for t in threads:
t.join()
# Multiprocessing - CPU bound
import multiprocessing
def cpu_task(n):
return sum(i*i for i in range(n))
with multiprocessing.Pool() as pool:
results = pool.map(cpu_task, [1000000] * 4)
Libraries and Frameworks (Q41-Q50)
Q41. What is NumPy? Give an example.
Answer: NumPy is a library for numerical computing in Python, providing arrays and mathematical functions.
import numpy as np
# Creating arrays
arr = np.array([1, 2, 3, 4, 5])
matrix = np.array([[1, 2, 3], [4, 5, 6]])
# Array operations
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
result = arr1 + arr2 # [5, 7, 9]
# Mathematical operations
arr = np.array([1, 2, 3, 4, 5])
print(np.mean(arr)) # 3.0
print(np.max(arr)) # 5
print(np.sum(arr)) # 15
Q42. What is Pandas? Give an example.
Answer: Pandas is a library for data manipulation and analysis, providing DataFrame and Series structures.
import pandas as pd
# Creating DataFrame
data = {
'Name': ['John', 'Jane', 'Bob'],
'Age': [25, 30, 35],
'City': ['NYC', 'LA', 'Chicago']
}
df = pd.DataFrame(data)
# Reading CSV
df = pd.read_csv('data.csv')
# Basic operations
print(df.head()) # First 5 rows
print(df.describe()) # Statistical summary
print(df['Age'].mean()) # Average age
Q43. What is the difference between Flask and Django?
Answer:
| Flask | Django |
|---|---|
| Microframework (minimal) | Full-featured framework |
| Lightweight, flexible | Batteries included |
| Good for small projects | Good for large projects |
| More control | More built-in features |
Q44. What is a virtual environment?
Answer: A virtual environment is an isolated Python environment that allows you to install packages without affecting the system Python.
# Creating virtual environment
python -m venv myenv
# Activating (Windows)
myenv\Scripts\activate
# Activating (Linux/Mac)
source myenv/bin/activate
# Installing packages
pip install requests
# Deactivating
deactivate
# Requirements file
pip freeze > requirements.txt
pip install -r requirements.txt
Q45. What is pip?
Answer: pip is Python's package installer. It allows you to install and manage Python packages from PyPI (Python Package Index).
# Installing package
pip install package_name
# Installing specific version
pip install package_name==1.2.3
# Uninstalling
pip uninstall package_name
# Listing installed packages
pip list
# Showing package info
pip show package_name
# Upgrading
pip install --upgrade package_name
Q46. What is the difference between list and array in Python?
Answer:
- List: Built-in, can hold different data types, flexible
- Array (NumPy): From NumPy library, homogeneous data types, faster for numerical operations
# List - can hold different types
my_list = [1, 2, "three", 4.5] # Valid
# NumPy array - homogeneous types
import numpy as np
my_array = np.array([1, 2, 3, 4]) # All integers
# my_array = np.array([1, 2, "three"]) # Converts to strings
# List operations are slower
my_list = [1, 2, 3, 4, 5]
result = [x * 2 for x in my_list] # Slower
# Array operations are faster
my_array = np.array([1, 2, 3, 4, 5])
result = my_array * 2 # Faster, vectorized
Q47. What is the difference between .py and .pyc files?
Answer:
- .py: Source code file (human-readable)
- .pyc: Compiled bytecode file (created automatically by Python)
__pycache__ directory to speed up program execution. Python uses them if the .py file hasn't changed.
Q48. What is __name__ == "__main__"?
Answer: This condition checks if the script is being run directly (not imported as a module).
# my_module.py
def greet(name):
return f"Hello, {name}!"
if __name__ == "__main__":
# This code runs only when script is executed directly
print(greet("World"))
print("This is the main program")
# When imported:
# import my_module
# The if block doesn't execute
# When run directly:
# python my_module.py
# The if block executes
Q49. What is the difference between == and is for None?
Answer: For None, both work the same, but is is preferred (PEP 8).
value = None
# Both work, but 'is' is preferred
if value == None: # Works but not recommended
print("None")
if value is None: # Preferred (PEP 8)
print("None")
# 'is' is faster and more Pythonic
# 'is' checks identity (same object)
# '==' checks equality (same value)
Q50. What are some best practices in Python?
Answer: Python best practices:
- Follow PEP 8 style guide
- Use meaningful variable names
- Write docstrings for functions and classes
- Use list comprehensions when appropriate
- Handle exceptions properly
- Use virtual environments
- Don't use
import * - Use
isfor None comparisons - Keep functions small and focused
- Use type hints (Python 3.5+)
Interview Tips
Preparation Tips
- Practice Coding: Write Python code daily on platforms like LeetCode, HackerRank
- Understand Concepts: Don't just memorize, understand the "why" behind each concept
- Know Your Libraries: Familiarize yourself with popular libraries (NumPy, Pandas, requests)
- Practice Problem Solving: Solve Python-specific problems
- Review Fundamentals: Strong basics are more important than advanced topics
During the Interview
- Think Aloud: Explain your thought process
- Ask Questions: Clarify requirements before coding
- Write Clean Code: Follow PEP 8, use meaningful names
- Handle Edge Cases: Consider None, empty lists, etc.
- Test Your Code: Walk through examples
Common Mistakes to Avoid
- Not understanding the difference between mutable and immutable types
- Confusing list and tuple
- Not handling exceptions
- Using
==instead ofisfor None - Not knowing about list comprehensions
- Ignoring PEP 8 style guide
Sign up here with your email
ConversionConversion EmoticonEmoticon