These questions will be a bit advanced(Intermediate) in terms of Python interview.
This is the continuity of Nail the Python Interview Questions.
The fields that these questions will help you in are:
• Python Developer
• Data Analyst
• Research Analyst
• Data Scientist
1. Search
Nail the Python Interview (Intermediate Questions)
Data Scian by Imad Adrees
·
Follow
13 min read
·
Oct 19, 2023
These questions will be a bit advanced(Intermediate) in terms
of Python interview.
This is the continuity of Nail the Python Interview Questions.
The fields that these questions will help you in are:
Python Developer
Data Analyst
2. Research Analyst
Data Scientist
Data Engineer
Let’s Dive into those questions:
Intermediate Interview Questions
1. Discuss the concept of list slicing in Python.
List slicing is a powerful feature in Python that allows you to
extract a portion of a list by specifying a start index, an end
index, and an optional step size. It follows the
format list[start:stop:step]:
start: The index at which the slice begins (inclusive).
stop: The index at which the slice ends (exclusive).
step: The step size between elements in the slice
(optional).
For example:
my_list = [1, 2, 3, 4, 5]
sliced_list = my_list[1:4] # Extracts elements 2, 3, and 4
3. 2. Explain the principles of Object Oriented
Programming(OOP).
In today’s world, Object-oriented programming is used in
most of the programs to create or design applications and
computer programs.
OOP is based on four principles:
Abstraction: Abstraction is the process of hiding the
implementation details of an object from the outside
world. This allows us to focus on the functionality of the
object without worrying about how it works internally.
Encapsulation: Encapsulation is the process of bundling
data and code together into a single unit. This makes it
easier to manage and maintain code, and it also helps to
protect data from unauthorized access.
Inheritance: Inheritance allows us to create new classes
based on existing classes. This allows us to reuse code
and create hierarchies of classes that reflect the
relationships between different types of objects.
Polymorphism: Polymorphism allows us to write code
that can be used with different types of objects. This
makes code more flexible and reusable.
3. Explain the use of decorators in Python with
examples.
4. Decorators in Python are functions that wrap or modify the
behaviour of other functions or methods. They are used to add
functionality to functions without changing their source code.
Decorators are often denoted by the @decorator_name syntax.
Here's an example:
def my_decorator(func):
def wrapper():
print("Something is happening before the function is
called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
In this example, my_decorator is a decorator that adds pre- and
post-processing steps to the say_hello() function.
4. How does Python’s garbage collection work, and why is
it important?
Python’s garbage collection automatically manages memory
by reclaiming objects that are no longer referenced or needed.
It uses a technique called reference counting and cyclic
garbage collection to track and clean up objects. Garbage
collection is essential because it prevents memory leaks and
5. ensures efficient memory usage in Python programs.
Developers don’t need to manually free memory, making
Python memory management more user-friendly.
5. Discuss the concept of multi-threading vs. multi-
processing in Python.
Multi-threading: Multi-threading involves running
multiple threads (smaller units of a process) within a
single process. Threads share the same memory space
and can be used for tasks that involve I/O operations.
However, due to the Global Interpreter Lock (GIL) in
CPython, threads may not fully utilize multiple CPU
cores for CPU-bound tasks.
Multi-processing: Multi-processing involves running
multiple processes, each with its own memory space and
Python interpreter. This allows for true parallelism on
multi-core processors, making it suitable for CPU-bound
tasks. Each process runs independently and
communicates using inter-process communication (IPC)
mechanisms.
6. Describe the difference between machine learning and
deep learning.
Machine learning and deep learning are both subfields of
artificial intelligence (AI). Machine learning is a broader field
that encompasses a variety of algorithms that can learn from
6. data and make predictions. Deep learning is a subset of
machine learning that uses artificial neural networks to learn
from data.
Machine learning algorithms typically work by first extracting
features from the data. Deep learning algorithms, on the other
hand, learn directly from the raw data.
7. How can you handle file I/O errors gracefully in
Python?
You can handle file I/O errors gracefully in Python
using try, except blocks. For example:
try:
with open('myfile.txt', 'r') as file:
data = file.read()
except FileNotFoundError:
print("File not found.")
except IOError as e:
print(f"An error occurred: {e}")
Here, we catch specific exceptions
like FileNotFoundError and IOError and provide appropriate
error messages or take corrective actions.
8. Explain the purpose of the super() function in Python.
7. The ‘super()’ function is used to call a method from a parent
class within a child class. It's often used in the __init__
method of a child class to invoke the constructor of the parent
class. This allows you to initialize attributes and behaviour
from the parent class while adding or overriding functionality
in the child class.
9. Write a function to find the longest common
subsequence of two strings.
Here is the code for the Longest Common Subsequence of two
strings:
def longest_common_subsequence(X, Y):
m = len(X)
n = len(Y)
'''Create a table to store lengths of longest common
suffixes of substrings'''
LCSuff = [[0 for k in range(n+1)] for l in range(m+1)]
# To store length of the longest common substring
length = 0
row, col = 0, 0
# Building the table in bottom-up manner
for i in range(m + 1):
for j in range(n + 1):
if (i == 0 or j == 0):
LCSuff[i][j] = 0
8. elif (X[i-1] == Y[j-1]):
LCSuff[i][j] = LCSuff[i-1][j-1] + 1
if length < LCSuff[i][j]:
length = LCSuff[i][j]
row = i
col = j
else:
LCSuff[i][j] = 0
'''If we have non-empty result, then insert all characters
from first character to last character of string'''
if length > 0:
resultStr = ["0"] * length
while LCSuff[row][col] != 0:
resultStr[length-1] = X[row - 1]
row -= 1
col -= 1
length -= 1
return "".join(resultStr)
else:
return ""
10. What is a context manager, and how is it used in
Python?
A context manager in Python is an object that defines the
methods __enter__() and __exit__() to set up and tear down a
context for a block of code. Context managers are typically
9. used with the with statement to ensure resources are acquired
and released properly. Common use cases include file
handling and acquiring locks.
Example with file handling:
pythonCopy code
with open('file.txt', 'r') as file:
data = file.read()
# File is automatically closed when the block exits
The ‘open()’ function is a built-in example of a context
manager.
11. How can you handle exceptions with multiple ‘except’
blocks in Python?
You can handle multiple types of exceptions in Python by
using multiple ‘except’ blocks, each one specifying a different
exception type. The ‘except’ blocks are evaluated in order,
and the first one that matches the raised exception is executed.
Here's an example:
try:
# Code that may raise exceptions
result = 10 / 0
except ZeroDivisionError:
10. print("Division by zero error")
except ValueError:
print("Value error")
except Exception as e:
print(f"An unexpected error occurred: {e}")
In this example, if a ZeroDivisionError occurs, the
first ‘except’ block is executed. If a ValueError occurs, the
second ‘except’ block is executed. If any other exception
occurs, the third ‘except’ block (catch-all) is executed.
12. Explain the differences between list comprehensions
and generator expressions.
List Comprehensions: List comprehensions create a new
list by iterating over an iterable (e.g., a list) and applying
an expression to each item in the iterable. They return a
list and eagerly compute all values. List comprehensions
use square brackets […].
Example:
squares = [x**2 for x in range(1, 6)] # Creates a list of squares
Generator Expressions: Generator expressions create a
generator object, which is iterable and generates values
lazily as needed. They use parentheses (…). Generator
11. expressions are memory-efficient and are useful when
dealing with large datasets.
Example:
squares_generator = (x**2 for x in range(1, 6))
# Creates a generator for squares
13. Discuss the use of the ‘collections’ module in Python.
The ‘collections’ module in Python provides specialized data
structures that are alternatives to built-in data types. Some
important classes in this module include:
namedtuple: Creates simple classes with named fields
for storing data.
deque: Double-ended queues for efficient inserts and
removals from both ends.
Counter: Counts the occurrences of elements in an
iterable.
OrderDict: A dictionary that maintains the order of keys.
defaultdict: A dictionary with default values for missing
keys.
12. The ‘collections’ module is useful for solving various data
manipulation and storage problems efficiently.
14. How do you implement inheritance in Python?
Inheritance in Python is implemented by creating a new class
that inherits attributes and methods from an existing class. The
existing class is called the “base class” or “parent class,” and
the new class is called the “derived class” or “child class.” The
derived class can extend or override the behaviour of the base
class.
Example:
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof!"
In this example, Dog is a derived class that inherits
the Speak() method from the Animal base class but provides
its own implementation.
15. How do you work with JSON data in Python?
13. Most of the information on the web is in JSON format. So it is
important to handle JSON data efficiently. To work with json
data we can use the ‘json’ module. This module provides
functions for decoding and encoding JSON data.
Here is an Example:
import json
# Encode a Python dictionary into JSON with indentation
data = {
"name": "Alice",
"age": 25,
"occupation": "Software Engineer"
}
# Use the 'indent' parameter for pretty printing
json_data = json.dumps(data, indent=4)
print(json_data)
# Decode the JSON data back into a Python dictionary
decoded_data = json.loads(json_data)
print(decoded_data)
16. How can you create and use a custom exception in
Python?
You can create a custom exception in Python by defining a
new class that inherits from the built-in Exception class or one
of its subclasses. Custom exceptions are useful for adding
application-specific error handling.
14. Example:
class MyCustomError(Exception):
def __init__(self, message):
super().__init__(message)
try:
raise MyCustomError("This is a custom exception.")
except MyCustomError as e:
print(f"Caught an exception: {e}")
17. Explain the purpose of the ‘itertools’ module in
Python.
The ‘itertools’ module in Python provides a set of fast,
memory-efficient tools for working with iterators, which are
objects that can be iterated (e.g., lists, tuples, and generators).
It includes functions for creating iterators for various
mathematical and combinatorial operations, such as
permutations, combinations, and Cartesian
products. ‘itertools’ simplifies common iteration tasks and
allows for more efficient memory usage when working with
large datasets.
18. Explain the concept of first-class functions in Python.
First-Class Functions in Python are the functions that can be
treated as objects which means they can be assigned to
15. variables, passed to other functions as arguments and returned
from other functions.
Example:
# Assign a function to a variable
def add_two_numbers(a, b):
return a + b
sum = add_two_numbers
# Pass a function as an argument to another function
def map(function, iterable):
result = []
for element in iterable:
result.append(function(element))
return result
numbers = [1, 2, 3, 4, 5]
squared_numbers = map(lambda x: x * x, numbers)
# Return a function from a function
def create_adder(x):
def adder(y):
return x + y
return adder
add_five = create_adder(5)
# Call the function returned by create_adder()
print(add_five(10))
19. Describe the principles of database connectivity in
Python.
16. Database connectivity in Python is the process of connecting
to databases and communicating with them using Python. This
can be achieved in multiple ways such as pymysql, psycopg2,
and sqlite3.
The basic steps for connecting to a database in Python are as
follows:
1.Import the required database library.
2.Create a connection object to the database.
3.Create a cursor object to execute SQL queries.
4.Execute the desired SQL queries using the cursor object.
5.Close the cursor object and the connection object.
20. How can you implement multi-threading in Python?
Multi-threading in Python can be implemented using the built-
in ‘threading’ module. Here's a simple example:
import threading
def print_numbers():
for i in range(1, 6):
print(f"Number: {i}")
def print_letters():
for letter in 'abcde':
print(f"Letter: {letter}")
17. thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_letters)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print("Both threads are done.")
In this example, two functions are executed concurrently using
threads, and the join() method is used to ensure both threads
finish before proceeding
21. Explain the purpose of the ‘@staticmethod’ decorator
in Python.
The ‘@staticmethod’ decorator is used to define a static
method within a class. Static methods are associated with the
class rather than instances of the class. They don't require
access to instance-specific data and can be called on the class
itself without creating an instance of the class.
Example:
class MathUtils:
@staticmethod
def add(x, y):
return x + y
18. result = MathUtils.add(3, 5)
# Calling a static method without creating an instance
Static methods are often used for utility functions that are
related to the class but don’t depend on instance-specific state.
22. Discuss the purpose of
the __str__ and __repr__ methods in Python.
__str__: The __str__ method is used to define the
informal or user-friendly string representation of an
object. It should return a string that provides a readable
and descriptive representation of the object. This method
is typically used for display purposes.
__repr__: The __repr__ method is used to define the
formal or unambiguous string representation of an
object. It should return a string that, ideally, can be used
to recreate the object. This method is primarily used for
debugging and development.
Example:
class MyClass:
def __init__(self, value):
self.value = value
def __str__(self):
return f"MyClass instance with value: {self.value}"
19. def __repr__(self):
return f"MyClass({self.value})"
23. What is the purpose of the ‘os’ module in Python, and
give examples of its usage.
The ‘os’ module in Python provides a portable way to use
operating system-dependent functionality, such as interacting
with the file system, working with directories, and running
system commands. Some examples of its usage include:
Working with Files and Directories:
import os
# Check if a file or directory exists
if os.path.exists('myfile.txt'):
print("File exists")
# Create a directory
os.mkdir('mydir')
# List files in a directory
files = os.listdir('mydir')
Running System Commands:
import os
# Execute a shell command
os.system('ls -l')
20. # Launch an external program
os.startfile('program.exe')
24. How do you serialize and deserialize objects in Python?
Serialization is the process of converting a Python object into
a format that can be stored or transmitted, such as JSON or
binary data. Deserialization is the reverse process, converting
serialized data back into a Python object. You can use modules
like ‘pickle’, ‘json’, or third-party libraries like ‘protobuf’ or
‘msgpack’ for serialization and deserialization.
Example using pickle:
import pickle
# Serialization
data = {'name': 'Alice', 'age': 30}
with open('data.pkl', 'wb') as file:
pickle.dump(data, file)
# Deserialization
with open('data.pkl', 'rb') as file:
loaded_data = pickle.load(file)te
25. How do you use Python’s regular expressions (regex)
module?
Regular expressions module in Python is used to search, match
and replace text. To use it, we need to first import it.
21. import re
Then, you can use ‘re.compile()’ function to create a regular
expression object.
This function takes a regular expression pattern as input and
returns a regular expression object as output.
Once you have created a regular expression object, you can
use it to match text against the regular expression pattern using
the re.search(), re.match(), or re.findall() function.
Finally, you can use the re.sub() function to replace text that
matches the regular expression pattern with a replacement
string.
26. What is the purpose of Python’s ‘logging’ module, and
how do you use it?
Python’s ‘logging’ module is a standard library module that
provides flexible and extensible ways for Python applications
to have logging systems.
To use the logging module, you first need to import it:
import logging
Then you need to create a logger object:
22. logger = logging.getLogger(‘my_logger’)
You can then use the logger object to log messages:
logger.debug(‘This is a debug message.’)
logger.info(‘This is an info message.’)
logger.warning(‘This is a warning message.’)
logger.error(‘This is an error message.’)
logger.critical(‘This is a critical message.’)
27. How do you handle circular references in Python?
Circular references occur when objects reference each other,
creating a loop that prevents Python’s reference count-based
garbage collector from properly cleaning up memory. You can
break circular references by manually setting references
to None or by using the gc (garbage collector)
module's gc.collect() method.
Example:
import gc
class Node:
def __init__(self):
self.next = None
node1 = Node()
node2 = Node()
node1.next = node2
23. node2.next = node1 # Circular reference
# Break the circular reference
node1.next = None
node2.next = None
# Trigger garbage collection (not always needed)
gc.collect()
28. Explain the purpose and usage of Python’s ‘assert’
statement.
The purpose of Python’s ‘assert’ statement is to test
assumptions about your code. It is a debugging tool that allows
you to catch and address issues early in the development
process.
It takes an expression as an argument. If the expression is
True, the ‘assert’ statement does nothing. If the expression
evaluates to False, the ‘assert’ statement raises an
‘AssertionError’ exception.
29. What is the purpose of the multiprocessing module in
Python?
The multiprocessing module in Python is used to create and
manage multiple processes, allowing for true parallelism on
multi-core processors. It provides a high-level interface for
creating, running, and synchronizing processes, making it
useful for CPU-bound tasks that can benefit from parallel
24. execution. Unlike threads (affected by the Global Interpreter
Lock), processes run independently and can fully utilize
multiple CPU cores.
30. Discuss the differences
between __getattr__() and __getattribute__() in Python.
__getattr__(self, name): This method is called when an
attribute is accessed that doesn't exist in the object's
namespace. It allows you to define custom behavior for
attribute access.
__getattribute__(self, name): This method is called for all
attribute access, whether the attribute exists or not. It's a
lower-level method that can be used for customizing
attribute access globally.
Caution should be exercised when
overriding __getattribute__() as it can affect all attribute
access and potentially lead to infinite recursion if not handled
carefully. __getattr__() is typically used for customizing
attribute access only when needed.
**********************************
Written by Data Scian by Imad Adrees