1. Is Python compiled, interpreted, or both?
- Only compiled language
- Only interpreted language
- Both compiled and interpreted
- Neither compiled nor interpreted
Correct Answer: Both compiled and interpreted
python myfile.py
Get the Preplance app for a seamless learning experience. Practice offline, get daily streaks, and stay ahead with real-time interview updates.
Get it on
Google Play
4.9/5 Rating on Store
Python · Complete Question Bank
Practice the complete collection of Python interview questions including theory, coding, MCQs and real interview problems.
Questions
145
Full database
Topics
89
Categorised
Difficulty
Mixed Levels
Easy Hard
Scroll through every important Python question asked in real interviews. Includes MCQs, subjective questions, and coding prompts.
Correct Answer: Both compiled and interpreted
python myfile.py
Browse more Python questions, explore related subjects, or practice full interview sets to strengthen your preparation.
Correct Answer: + operator
a=[1,2,3]; b=[4,5]; res=a+b
Correct Answer: while loop
i=0 while i<5: print(i); i+=1
Correct Answer: floor()
import math math.floor(3.7)
Correct Answer: / gives float, // gives integer
print(5/2, 5//2)
Correct Answer: Yes required
if True:
print('Yes')Correct Answer: Yes, any function
def add(x,y): return x+y def apply(f,a,b): return f(a,b) apply(add,3,5)
Correct Answer: Type decided at runtime
x=10 x='Hi'
Correct Answer: Does nothing
def temp(): pass
def f(x): x.append(1) a=[0]; f(a); print(a)
square = lambda x: x*x print(square(4))
a=[1,2,3] squares=[x*x for x in a]
def demo(*a, **b): print(a,b)
for i in range(5): if i==2: continue if i==4: break print(i)
myset={1,2,3}
mydict={'a':1,'b':2}Correct Answer: List is mutable; tuple is immutable
t = (1,2,3) # t[0] = 9 # TypeError lst = [1,2,3]; lst[0] = 9
Correct Answer: Insertion order preserved
d = {}
d['a']=1; d['c']=3; d['b']=2
print(list(d.keys())) # ['a','c','b']Correct Answer: O(1) average
s = {1,2,3}
print(2 in s) # fastCorrect Answer: [x*x for x in nums]
nums=[1,2,2,3] sq=[x*x for x in nums] # [1,4,4,9]
Correct Answer: import copy; new = copy.deepcopy(old)
import copy old=[[1],[2]] new=copy.deepcopy(old) new[0][0]=9 # old unchanged
Correct Answer: d1 | d2
a={'x':1}
b={'y':2,'x':9}
c=a|b # {'x':9,'y':2}Correct Answer: collections.deque
from collections import deque q=deque() q.append(1); q.append(2); q.popleft()
Correct Answer: heapq
import heapq h=[] heapq.heappush(h,3); heapq.heappush(h,1) print(heapq.heappop(h)) # 1
Correct Answer: c.most_common(3)
from collections import Counter
c=Counter('banana')
print(c.most_common(3))users=['a','b','b']
unique=set(users)
points={('lat','lon'): (30.1,78.0)}import copy orig=[[1],[2]] sh = copy.copy(orig) dp = copy.deepcopy(orig) sh[0][0]=9 # orig changes # dp edits do not affect orig
# stack stack=[]; stack.append(1); stack.append(2); stack.pop() # queuerom collections import deque q=deque([1,2]); q.append(3); q.popleft()
names=['a','bb','ccc']
lengths={n:len(n) for n in names if len(n)>1}from collections import defaultdict
groups=defaultdict(list)
for k,v in [('a',1),('a',2)]:
groups[k].append(v)
print(dict(groups))Correct Answer: Use def f(x, arr=None): then set arr = [] inside
def add_item(x, arr=None):
if arr is None:
arr = []
arr.append(x)
return arrCorrect Answer: Local, Enclosing, Global, Builtins
x='G'
def outer():
x='E'
def inner():
x='L'
return x
return inner()
print(outer())Correct Answer: Modify or extend a function's behavior without changing its source
def log(fn):
def wrap(*a, **k):
print('call', fn.__name__)
return fn(*a, **k)
return wrap
@log
def add(x,y): return x+yCorrect Answer: Instance methods receive self; class methods receive cls; static methods receive neither
class A:
def m(self): return 'inst'
@classmethod
def c(cls): return 'class'
@staticmethod
def s(): return 'static'Correct Answer: C3 linearization (Method Resolution Order)
class A: pass class B(A): pass class C(B, A): pass print(C.__mro__)
Correct Answer: __repr__ is unambiguous; __str__ is readable
class P:
def __init__(self,x): self.x=x
def __repr__(self): return f'P(x={self.x})'
def __str__(self): return f'Point {self.x}'Correct Answer: To expose an attribute-like API while running getter or setter logic
class User:
def __init__(self,name): self._name=name
@property
def name(self): return self._name.title()
@name.setter
def name(self,v): self._name=v.strip()Correct Answer: Auto-generating boilerplate like __init__, __repr__, and comparisons
from dataclasses import dataclass
@dataclass
class Point:
x:int
y:intCorrect Answer: Memory usage per instance can drop by removing __dict__
class Light:
__slots__ = ('on',)
def __init__(self): self.on=Falsedef counter():
count=0
def inc():
nonlocal count
count += 1
return count
return inc
c = counter(); c(); c()import time, functools
def timed(fn):
@functools.wraps(fn)
def wrap(*a, **k):
t0=time.perf_counter()
try:
return fn(*a, **k)
finally:
dt=time.perf_counter()-t0
print(fn.__name__, 'took', dt)
return wrapfrom abc import ABC, abstractmethod
class Store(ABC):
@abstractmethod
def save(self, item): ...
class DB(Store):
def save(self, item): passclass Bag:
items=[] # shared
def __init__(self):
self.things=[] # per instance
b1=Bag(); b2=Bag()
b1.things.append(1)
Bag.items.append('X')class Engine:
def start(self): return 'start'
class Car:
def __init__(self, engine): self.engine=engine
def go(self): return self.engine.start()Correct Answer: x
with open('report.txt', 'x', encoding='utf-8') as f:
f.write('first run only')Correct Answer: It auto-closes the file even if an exception occurs
with open('data.txt', 'r', encoding='utf-8') as f:
for line in f:
process(line)Correct Answer: Iterate line by line: for line in f
with open('big.log','r',encoding='utf-8') as f:
for line in f:
handle(line)Correct Answer: Explicitly set encoding='utf-8'
with open('notes.txt','r',encoding='utf-8') as f:
txt=f.read()Correct Answer: open('out.csv','w', newline='')
import csv
with open('out.csv','w',newline='',encoding='utf-8') as f:
w=csv.writer(f)
w.writerow(['id','name'])Correct Answer: json
import json
with open('cfg.json') as f:
cfg=json.load(f)Correct Answer: from .utils import helper
# inside package module from .utils import helper helper.run()
Correct Answer: It marks a directory as a package and can expose the public API
# mypkg/__init__.py from .core import run __all__=['run']
Correct Answer: sys.path
import sys print(sys.path[0])
Correct Answer: When handling images or ZIP files
with open('photo.jpg','rb') as f:
buf=f.read(1024)class Locker:
def __enter__(self): print('acquire'); return self
def __exit__(self, exc_type, exc, tb): print('release')
with Locker() as l:
do_work()from pathlib import Path
p = Path('logs')/'app.log'
text = p.read_text(encoding='utf-8')def chunks(f, size=1024*1024):
while True:
b=f.read(size)
if not b: break
yield b
with open('big.bin','rb') as f:
for c in chunks(f):
process(c)import importlib, mymod # edit mymod on disk mymod = importlib.reload(mymod)
mypkg/ __init__.py # from .core import run; __all__=['run'] core.py utils.py
Correct Answer: try → except → else → finally
try:
do_work()
except ValueError:
fix()
else:
commit()
finally:
close()Correct Answer: except (A, B):
try:
risky()
except (KeyError, IndexError):
recover()Correct Answer: It hides SystemExit and KeyboardInterrupt by default
try:
run()
except Exception as e:
log(e)
raiseCorrect Answer: It chains exceptions and keeps the original context
try:
low()
except OSError as e:
raise RuntimeError('storage failed') from eCorrect Answer: Exception
class AppError(Exception):
pass
class ConfigError(AppError):
passCorrect Answer: For invariant checks that should be optimized away with O opt
def area(r):
assert r >= 0
return 3.14*r*rCorrect Answer: logging supports levels, handlers, and structured messages
import logging
logging.exception('failed to save')Correct Answer: Ignores ValueError within the with block
from contextlib import suppress
with suppress(FileNotFoundError):
os.remove('tmp.txt')Correct Answer: Exception is a subclass of BaseException
print(issubclass(Exception, BaseException)) # True
f=None
try:
f=open('data.txt','r',encoding='utf-8')
use(f)
finally:
if f: f.close()import pdb pdb.set_trace() result = compute(x) # commands: n, s, c, p var, w
import logging
try:
risky()
except Exception:
logging.exception('risky failed with inputs=%s', args)# EAFP
d = {}
try:
v = d['x']
except KeyError:
v = 0
# LBYL
v = d['x'] if 'x' in d else 0for attempt in range(5):
try:
return call()
except TimeoutError:
sleep(0.1 * 2**attempt)
raise RuntimeError('give up')Correct Answer: Defining __iter__ that returns an iterator
class Box:
def __init__(self, items): self.items=items
def __iter__(self): return iter(self.items)Correct Answer: It must implement __iter__ returning self and __next__
class Count:
def __init__(self,n): self.i=0; self.n=n
def __iter__(self): return self
def __next__(self):
if self.i>=self.n: raise StopIteration
self.i+=1; return self.iCorrect Answer: It saves memory by producing items lazily
total = sum(x*x for x in range(10_000_000))
Correct Answer: It sets StopIteration with the value attached
def g():
yield 1
return 99
# next after yield raises StopIteration(99)Correct Answer: Delegates iteration and forwards send and throw
def outer():
result = yield from inner()
yield resultCorrect Answer: chain
from itertools import chain
for x in chain([1,2],[3,4]):
print(x)Correct Answer: Caching pure functions with repeated inputs
from functools import lru_cache
@lru_cache(maxsize=256)
def fib(n):
return n if n<2 else fib(n-1)+fib(n-2)Correct Answer: Freezes some arguments to create a new callable
from functools import partial pow2 = partial(pow, 2) print(pow2(10)) # 1024
Correct Answer: __get__, __set__, __delete__
class NonEmpty:
def __set__(self, obj, val):
if not val: raise ValueError('empty')
obj.__dict__['name']=val
def __get__(self, obj, owner):
return obj.__dict__['name']from contextlib import contextmanager
@contextmanager
def opened(path):
f=open(path,'r',encoding='utf-8')
try:
yield f
finally:
f.close()def read_lines(f):
for line in f: yield line.strip()
def only_errors(lines):
for s in lines:
if 'ERROR' in s: yield s
with open('app.log') as f:
for msg in only_errors(read_lines(f)): print(msg)import asyncio, aiohttp
async def fetch(url):
async with aiohttp.ClientSession() as s:
async with s.get(url) as r:
return await r.text()
asyncio.run(fetch('https://example.com'))def coro():
total=0
while True:
x = yield total
if x is None: break
total += x
c = coro(); next(c)
print(c.send(3)); print(c.send(4)); c.throw(GeneratorExit)class NonEmpty:
def __set__(self,obj,val):
if not val: raise ValueError('empty')
obj.__dict__['name']=val
class User:
name = NonEmpty()
def __init__(self, name): self.name=nameCorrect Answer: Shallow copy copies only the outer container
import copy orig=[[1],[2]] sh=copy.copy(orig) dp=copy.deepcopy(orig) sh[0][0]=9 # orig also changes # dp edits do not affect orig
Correct Answer: copy.deepcopy()
import copy b = copy.deepcopy(a)
Correct Answer: list and tuple
lst=[1,2]; lst.append(3) tup=(1,2) # cannot append
Correct Answer: The immediate size of the object header and payload
import sys print(sys.getsizeof([1,2,3]))
Correct Answer: Small integers are interned and reused by the runtime
a=5; b=5 print(id(a)==id(b)) # often True
Correct Answer: bytearray
buf = bytearray(b'ABC') buf[0]=97 # a
Correct Answer: Zero-copy slices and views
data=b'x'*1_000_000 mv=memoryview(data) chunk=mv[100:200]
Correct Answer: Reduces memory, may slightly speed access
class Row:
__slots__=('a','b')
def __init__(self,a,b): self.a=a; self.b=bCorrect Answer: timeit
import timeit
print(timeit.timeit('sum(range(1000))', number=1000))import gc print(gc.get_threshold()) # gc.collect() can force a cycle collection
import weakref class A: pass obj=A() w=weakref.ref(obj) obj=None # target can be collected
import cProfile, pstats
cProfile.run('main()', 'prof')
p=pstats.Stats('prof'); p.sort_stats('tottime').print_stats(20)nums=list(range(1_000_000)) # better total=sum(nums) # with numpy # import numpy as np; total=np.sum(np.array(nums))
# I O bound: threading # CPU bound: multiprocessing # mix with concurrent.futures for a simple API
import tracemalloc tracemalloc.start() # run workload print(tracemalloc.get_traced_memory())
Correct Answer: They execute optimized C loops and use contiguous arrays
import numpy as np x=np.arange(1_000_000) y=x*2 # vectorized C loop
Correct Answer: .loc is label based; .iloc is integer position based
df.loc['2025-01-01'] df.iloc[0:10]
Correct Answer: Using .loc with a mask, then assign
m = df['a']>0 df.loc[m, 'b'] = 1
Correct Answer: Use .agg with a dict or list of funcs
df.groupby('city').agg({'sales':['sum','mean'],'id':'count'})Correct Answer: Use dtype and usecols to limit types and columns
pd.read_csv('data.csv', usecols=['id','price'], dtype={'id':'int32','price':'float32'})Correct Answer: You must pass timeout; otherwise it can wait forever
import requests r = requests.get(url, timeout=(3.05, 10))
Correct Answer: Connection pooling and shared headers or cookies
s=requests.Session(); s.headers.update({'Authorization':'Bearer X'})
s.get(url)Correct Answer: Add ? after the quantifier
import re
re.findall('<p>.*?</p>', html, flags=re.S)Correct Answer: They allow backslashes without Python interpreting escapes
pattern = re.compile(r'\d{4}-\d{2}-\d{2}')Correct Answer: json is interoperable and safer to load from clients
import json
payload=json.dumps({'ok':True})from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
s=requests.Session()
retry=Retry(total=3, backoff_factor=0.5, status_forcelist=[429,502,503,504])
s.mount('https://', HTTPAdapter(max_retries=retry))df['z'] = (df['x']+df['y']).clip(lower=0) # slower # df['z']=df.apply(lambda r: max(r.x+r.y,0), axis=1)
m=re.search(r'(?P<yyyy>\d{4})-(?P<mm>\d{2})-(?P<dd>\d{2})', s)
year=m.group('yyyy')from zoneinfo import ZoneInfo
from datetime import datetime
now=datetime.now(tz=ZoneInfo('Asia/Kolkata'))it=pd.read_csv('big.csv', chunksize=200_000, usecols=['id','amt'], dtype={'id':'int32','amt':'float32'})
for chunk in it:
process(chunk)rows=[]; url=BASE
while url:
r=s.get(url, timeout=10)
data=r.json(); rows+=data['items']
url=data.get('next')
df=pd.DataFrame(rows)Correct Answer: O(n)
def two_sum(nums, target):
pos = {}
for i, x in enumerate(nums):
y = target - x
if y in pos:
return pos[y], i
pos[x] = i
return NoneCorrect Answer: Use collections.Counter to compare counts
from collections import Counter
def is_anagram(a,b):
return Counter(a) == Counter(b)Correct Answer: Longest substring without repeating characters
def longest_unique(s):
seen, left, best = {}, 0, 0
for right, ch in enumerate(s):
if ch in seen and seen[ch] >= left:
left = seen[ch] + 1
seen[ch] = right
best = max(best, right-left+1)
return bestCorrect Answer: bisect_left
from bisect import bisect_left idx = bisect_left([1,2,2,3], 2) # 1
Correct Answer: Stable, TimSort
data=[('bob',3),('bob',1)]
print(sorted(data, key=lambda t:t[0]))Correct Answer: heapq.nlargest(k, lst)
import heapq best = heapq.nlargest(3, [5,1,8,4,9])
Correct Answer: dict.fromkeys(lst).keys()
unique = list(dict.fromkeys([3,1,3,2,1])) # [3,1,2]
Correct Answer: collections.Counter(items)
from collections import Counter freq = Counter(['a','b','a'])
Correct Answer: Use key=lambda s: (s.name, -s.score)
students = sorted(students, key=lambda s: (s.name, -s.score))
def max_sum_k(nums, k):
s = sum(nums[:k]); best = s
for i in range(k, len(nums)):
s += nums[i] - nums[i-k]
best = max(best, s)
return bestfrom collections import defaultdict
def count_subarrays_k(nums, K):
pref, seen, ans = 0, defaultdict(int), 0
seen[0] = 1
for x in nums:
pref += x
ans += seen[pref-K]
seen[pref] += 1
return ansdef lower_bound(a, target):
lo, hi = 0, len(a)
while lo < hi:
mid = (lo + hi) // 2
if a[mid] < target:
lo = mid + 1
else:
hi = mid
return lodef pair_sum_sorted(a, target):
i, j = 0, len(a)-1
while i < j:
s = a[i] + a[j]
if s == target: return i, j
if s < target: i += 1
else: j -= 1
return Nonedef kadane(nums):
best = cur = nums[0]
for x in nums[1:]:
cur = max(x, cur + x)
best = max(best, cur)
return bestCorrect Answer: To isolate dependencies from the system Python
python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install -r requirements.txt
Correct Answer: Absolute imports from the package root
from myapp.core.service import run # Prefer absolute over: from .core import service
Correct Answer: DEBUG < INFO < WARNING < ERROR < CRITICAL
import logging
logging.basicConfig(level=logging.INFO)
log = logging.getLogger(__name__)
log.info('service started')Correct Answer: In environment variables
import os
DB_URL = os.environ['DATABASE_URL']
DEBUG = os.getenv('DEBUG','0')=='1'Correct Answer: pyproject.toml
[project] name = 'myapp' version = '0.1.0' [build-system] requires = ['setuptools','wheel'] build-backend = 'setuptools.build_meta'
Correct Answer: They enable static analysis and better tooling
from typing import List
def total(xs: List[int]) -> int:
return sum(xs)Correct Answer: On successful resource creation
# pseudo FastAPI
return JSONResponse(obj, status_code=201, headers={'Location': url})Correct Answer: PUT
# Request
PUT /users/42 {"name":"A"}
# Repeat same request → same final stateCorrect Answer: Use monkeypatch or mocks to replace network calls
def test_client(monkeypatch):
monkeypatch.setattr('client.http_get', lambda url: {'ok':True})
assert my_call()==Trueproject/
pyproject.toml
src/myapp/{api,core,adapters,utils}
tests/{unit,integration}class NotFoundError(Exception): ...
# API edge
try:
svc.get_user(id)
except NotFoundError:
return 404, {'error':'not found'}class Service:
def __init__(self, repo): self.repo=repo
def build():
repo = SqlRepo(url)
return Service(repo)import os API_KEY = os.environ['PAYMENT_KEY'] # pulled from a secret store in production
import asyncio
async def main():
await asyncio.gather(fetch(a), fetch(b))
asyncio.run(main())