Learn/Python

Python fundamentals

Output prediction and multiple choice questions covering the mechanics that trip people up.

287 questions16 topics
Variables & Types19 questions
Floor division resultEasy
None compared to zeroEasy
Augmented assignment on immutableEasy
Which type is mutable?Easy
Adding int and floatEasy
String repetitionEasy
Variable rebinding changes typeEasy
Boolean arithmeticEasy
Chained comparisonsEasy
Floor division with negativesEasy
Dividing two intsEasy
Which type is immutable?Easy
Boolean as indexEasy
String repetition with zeroEasy
Chained equality comparisonEasy
Identity vs equalityMedium
Walrus operator use caseMedium
Walrus operator in a comprehensionMedium
Small integer cachingHard
Control Flow20 questions
any() and all() short-circuitEasy
Conditional expression (ternary)Easy
Falsy values in PythonEasy
Short-circuit evaluation with andEasy
break exits only the innermost loopEasy
zip() stops at the shortestEasy
enumerate() with a start valueEasy
match statement (Python 3.10+)Easy
continue skips the rest of the iterationEasy
Purpose of the pass statementEasy
Non-empty container is truthyEasy
Nested ternary expressionEasy
enumerate() default startEasy
match with a wildcardEasy
zip() with three iterablesEasy
pass inside an if blockEasy
for-else clauseMedium
Nested list comprehensionMedium
for-else with break triggeredMedium
Nested comprehension with filterMedium
Lists21 questions
Slice creates a shallow copyEasy
append vs extendEasy
Negative indexingEasy
in operator on a listEasy
sort() vs sorted()Easy
list.pop() with no argumentEasy
Extended unpacking with *Easy
del vs remove()Easy
append adds a nested listEasy
Negative index with assignmentEasy
sort() returns NoneEasy
pop() return valueEasy
in operator with a nested listEasy
Unpacking with star at the frontEasy
remove() on duplicatesEasy
Mutable default argument trapMedium
List comprehension variable scopeMedium
Slicing beyond boundsMedium
Mutable default fixed with NoneMedium
Generator expression scopeMedium
List multiplication with mutable elementsHard
Dictionaries22 questions
Dict comprehensionEasy
Missing key: [] vs .get()Easy
collections.defaultdict purposeEasy
Merging dicts with update()Easy
dict.pop() vs del d[key]Easy
Unhashable key typeEasy
Iterating over a dictEasy
Dictionary key ordering (Python 3.7+)Easy
Updating a key preserves its positionEasy
get() with no defaultEasy
Dict merge with | operator (Python 3.9+)Easy
defaultdict(int) for countingEasy
Dict comprehension with filterEasy
pop() with a default on missing keyEasy
Iterating with .items()Easy
Shallow copy of a nested dictMedium
collections.Counter most_common()Medium
setdefault() behaviorMedium
Why dict keys must be hashableMedium
setdefault() return valueMedium
Counter arithmeticMedium
Deep copy vs shallow copyMedium
Functions20 questions
Functions without returnEasy
Closure captures variable by referenceEasy
*args collects positional argumentsEasy
Lambda as sort keyEasy
What happens without a base caseEasy
Unpacking into function callEasy
map() returns an iteratorEasy
Forgetting to return a computed valueEasy
Lambda with multiple argumentsEasy
Tracing a simple recursive functionEasy
filter() is also lazyEasy
LEGB scope lookupMedium
When are default argument values evaluated?Medium
Keyword-only argumentsMedium
Generator function with yieldMedium
nonlocal keywordMedium
Local variable shadows globalMedium
Mutable default argument trapMedium
Exhausted generator raises StopIterationMedium
Calling a keyword-only function positionallyMedium
Strings18 questions
Strings are immutableEasy
f-string interpolationEasy
Substring check with inEasy
f-string format specifiersEasy
strip() removes leading and trailing whitespaceEasy
split() and join() round-tripEasy
str.replace() returns a new stringEasy
Case methods return new stringsEasy
Triple-quoted string newlinesEasy
strip() with a custom character setEasy
split() default splits on whitespaceEasy
in checks for substring, not a character setEasy
Triple-quoted string with leading newlineEasy
Efficient string buildingMedium
startswith with a tuple of prefixesMedium
str vs bytesMedium
Why += on strings is slow in a loopMedium
startswith with a tuple of prefixesMedium
Comprehensions16 questions
Dict comprehensionEasy
Filtering with ifEasy
Set comprehension deduplicatesEasy
List comprehension basicsEasy
Set comprehension from a stringEasy
Generator expression vs list comprehensionMedium
Ternary inside a comprehensionMedium
Dict comprehension from two listsMedium
Comprehension vs map() — readabilityMedium
Ternary vs filter if in a comprehensionMedium
Generator expression consumed onceMedium
Nested comprehension — flattenHard
Nested comprehension with filterHard
Variable scope in comprehensionsHard
Walrus operator in comprehensionHard
Regular for loop vs comprehension — variable leakageHard
Error Handling17 questions
Basic try/exceptEasy
Catching the right exception typeEasy
finally always runsEasy
finally runs even when no exception occursEasy
Custom exception classMedium
except Exception vs bare exceptMedium
else clause on tryMedium
Raising exceptionsMedium
Re-raising with bare raiseMedium
contextlib.suppressMedium
Catching multiple exceptions in one clauseMedium
else does not run when exception is raisedMedium
Exception hierarchy — BaseException vs ExceptionMedium
Catching a custom exception by its parent typeMedium
Order matters in multiple except clausesMedium
Exception chaining with raise fromHard
with statement as context managerHard
Iterators & Generators15 questions
zip basicsEasy
enumerate gives index and valueEasy
zip stops at the shortest iterableEasy
enumerate default startEasy
Unzipping with zip(*)Medium
Generator function with yieldMedium
StopIteration when exhaustedMedium
Generator memory advantageMedium
filter() with None removes falsy valuesMedium
map() is lazyMedium
Chaining iterablesMedium
zip(*) to transpose a matrixMedium
chain.from_iterableMedium
Sending values into a generatorHard
Infinite generator patternHard
Classes17 questions
__repr__ vs __str__Easy
Instance variable vs class variableEasy
__init__ basicsEasy
Shadowing a class variable with an instance variableEasy
__init__ with a default parameterEasy
Inheritance and super()Medium
@classmethod vs @staticmethodMedium
@property setterMedium
Dunder methods __len__ and __eq__Medium
@property getterMedium
super() in __init__Medium
@classmethod as an alternative constructorMedium
dataclass basicsHard
Mutable default argument in __init__ trapHard
Method resolution order (MRO)Hard
__slots__ purposeHard
dataclass field with default_factoryHard
Functional Tools18 questions
sorted() with key=Easy
sorted() vs list.sort()Easy
lambda basicsEasy
list.sort() returns NoneEasy
Sorting by a field with lambdaMedium
lambda limitationsMedium
functools.reduceMedium
functools.partialMedium
filter() removes falsy valuesMedium
functools.lru_cacheMedium
reduce with an initial valueMedium
partial with positional argumentsMedium
lru_cache with unhashable argumentsMedium
operator.itemgetter vs lambdaHard
Argument order rulesHard
*args and **kwargs unpackingHard
Building a dict with zip and dict()Hard
dict comprehension from two listsHard
Decorators18 questions
@ is syntactic sugarEasy
Basic wrapper patternEasy
Logging decorator outputEasy
Decorator that prints after the callEasy
functools.wraps preserves __name__Medium
Class used as a decoratorMedium
Stacking decorators - order of applicationMedium
Decorator factory with argumentsMedium
Memoization decoratorMedium
Decorator factory with a prefix argumentMedium
Three stacked decoratorsMedium
Cache shared across two decorated instancesMedium
Class decorator storing last argumentMedium
Preserving signature for introspectionHard
When decorator code runsHard
Mutable state in a decorator closureHard
@staticmethod stacked with a custom decoratorHard
Decorator factory - when each level runsHard
Modules & Packages16 questions
What __init__.py does in a packageEasy
import math vs from math import sqrtEasy
What if __name__ == '__main__': doesEasy
import alias with 'as'Easy
__name__ value when importedEasy
__all__ and 'from module import *'Medium
Relative imports with 'from . import'Medium
Module vs package - what's the differenceMedium
How Python resolves imports via sys.pathMedium
Importing the same module twiceMedium
__all__ does not hide names from direct importMedium
Namespace packages in Python 3.3+Hard
importlib.import_module() and when you need itHard
Circular imports and the standard fixHard
Deleting from sys.modules and re-importingHard
Why deferred imports fix circular dependencyHard
File I/O17 questions
Why prefer 'with open()' over manual close()Easy
readlines() vs iterating the file objectEasy
open() modes: r, w, and aEasy
open() 'x' exclusive creation modeEasy
Iterating a file object vs readlines()Easy
Text mode vs binary modeMedium
json.dump vs json.dumpsMedium
pathlib.Path.stemMedium
csv.reader vs csv.DictReaderMedium
What open() returns and what happens if you don't close itMedium
json.load vs json.loadsMedium
csv.writer vs csv.DictWriterMedium
seek(0) after consuming the fileHard
Reading a binary file in text modeHard
open('w') on a path whose parent directory doesn't existHard
pathlib.Path.glob() - ** vs *Hard
tell() tracks file positionHard
Regular Expressions17 questions
What re.findall returnsEasy
Raw strings in regex patternsEasy
re.search vs re.match - key differenceEasy
re.match anchors to the startEasy
Raw string vs regular string in a patternEasy
re.compile - when and whyMedium
re.sub replacementMedium
Capturing groups and .groups()Medium
re.split on whitespaceMedium
Greedy vs lazy quantifiersMedium
re.sub with a count limitMedium
Greedy quantifier on a repeated patternMedium
Positive lookahead (?=...)Hard
re.DOTALL changes what . matchesHard
Named groups (?P<name>...)Hard
Non-capturing groups (?:...)Hard
Negative lookahead (?!...)Hard
Type Hints16 questions
What Optional[str] meansEasy
Basic function annotation syntaxEasy
Type hints are not enforced at runtimeEasy
Union[int, str] vs int | str - version compatibilityMedium
list[str] vs List[str] from typingMedium
Callable annotation with argumentsMedium
TypedDict for structured dictsMedium
What from __future__ import annotations doesMedium
Callable with no fixed argumentsMedium
TypeVar - preserving type identityHard
Protocol - structural vs nominal subtypingHard
get_type_hints() vs __annotations__ with future annotationsHard
@overload - when Union is not enoughHard
@overload - which body actually runsHard
Protocol vs ABC - the registration differenceHard
TypeVar bound - restricting the type rangeHard