Foundation Quiz
Quiz
a = [1, 2, 3] followed by b = a and then b.append(4)?b = a creates a reference to the same list object, not a copy. When you modify b, you’re modifying the same object that a references. To create an independent copy, use b = a.copy().b = a creates a reference to the same list object, not a copy. When you modify b, you’re modifying the same object that a references. To create an independent copy, use b = a.copy().False in a boolean context?0, 0.0, 0j), empty sequences ("", [], (), {}), None, and False. Note that [0] is a non-empty list containing one element, so it’s truthy.0, 0.0, 0j), empty sequences ("", [], (), {}), None, and False. Note that [0] is a non-empty list containing one element, so it’s truthy.1 < x < 10 is equivalent to 1 < x and x < 10 in Python.1 < x < 10 is syntactic sugar for 1 < x and x < 10, making code more readable.1 < x < 10 is syntactic sugar for 1 < x and x < 10, making code more readable.x = 5
x += 3
x *= 2
print(x)x = 5, then x += 3 makes x = 8, then x *= 2 makes x = 16. Assignment operators modify the variable in place.x = 5, then x += 3 makes x = 8, then x *= 2 makes x = 16. Assignment operators modify the variable in place.:=) allows you to assign a value to a variable and use that value in the same expression, e.g., if (n := len(data)) > 10::=) allows you to assign a value to a variable and use that value in the same expression, e.g., if (n := len(data)) > 10:for i in range(3):
count = 0
count += i
print(count, end=' ')count is declared inside the loop, so it resets to 0 on every iteration. Then it adds i (0, 1, 2) and prints. If count were declared outside the loop, it would accumulate values.count is declared inside the loop, so it resets to 0 on every iteration. Then it adds i (0, 1, 2) and prints. If count were declared outside the loop, it would accumulate values.count is initialized—inside or outside the loop?None?is (not ==) for None checks. is checks object identity, while == checks value equality. Since None is a singleton (there is exactly one None object in memory), is None is the correct and idiomatic approach.is (not ==) for None checks. is checks object identity, while == checks value equality. Since None is a singleton (there is exactly one None object in memory), is None is the correct and idiomatic approach.False and expensive_function() will execute expensive_function().and is False, the result is already known to be False, so Python never evaluates the right side. This is an optimization that can prevent unnecessary computations.and is False, the result is already known to be False, so Python never evaluates the right side. This is an optimization that can prevent unnecessary computations.What is the time complexity of this code?
for i in range(n):
for j in range(n):
print(i, j)n times. The outer loop runs n times, and for each iteration of the outer loop, the inner loop also runs n times. Total operations: n × n = n². This is quadratic time complexity.n times. The outer loop runs n times, and for each iteration of the outer loop, the inner loop also runs n times. Total operations: n × n = n². This is quadratic time complexity.fruits = ['apple', 'banana', 'cherry']
for index, fruit in _____(fruits):
print(f"{index}: {fruit}")enumerate() function returns both the index and value while iterating over a sequence. It’s more Pythonic than using range(len(fruits)) and manually indexing.enumerate() function returns both the index and value while iterating over a sequence. It’s more Pythonic than using range(len(fruits)) and manually indexing.The Walrus Operator (:=)
Introduced in Python 3.8+, it allows you to assign a value to a variable AND use that value in the same expression.
General Form:
variable := expressionExample:
if (n := len(data)) > 10:
print(f"List has {n} elements")This evaluates len(data), assigns it to n, and uses it in the comparison—all in one line.
Did you get it right?
else clause with loops in Python?for and while loops can have an else clause that executes only when the loop completes normally without encountering a break. This is useful for search operations where you want to know if the search completed without finding the target.for and while loops can have an else clause that executes only when the loop completes normally without encountering a break. This is useful for search operations where you want to know if the search completed without finding the target.result = 0 or 5 or 10
print(result)or operator returns the first truthy value. Since 0 is falsy, it skips to 5, which is truthy, and returns it immediately (short-circuit evaluation). The value 10 is never evaluated.or operator returns the first truthy value. Since 0 is falsy, it skips to 5, which is truthy, and returns it immediately (short-circuit evaluation). The value 10 is never evaluated.or returns the first truthy value, not True/False.timeout = seconds or 30 when seconds can legitimately be 0?0 is falsy in Python, 0 or 30 evaluates to 30. If 0 is a valid timeout value (e.g., no timeout), this breaks the logic. The fix is: timeout = 30 if seconds is None else seconds, which explicitly checks for None only.0 is falsy in Python, 0 or 30 evaluates to 30. If 0 is a valid timeout value (e.g., no timeout), this breaks the logic. The fix is: timeout = 30 if seconds is None else seconds, which explicitly checks for None only.x, y = 10, 20
x, y = y, x
print(x, y)(y, x) is evaluated first as a tuple (20, 10), then unpacked to x, y. No temporary variable needed!(y, x) is evaluated first as a tuple (20, 10), then unpacked to x, y. No temporary variable needed!Short-Circuit Evaluation
Python stops evaluating a logical expression as soon as the final result is determined.
With and:
- If left side is
False, result must beFalse—don’t evaluate right side False and expensive_function()→ Never calls function
With or:
- If left side is
True, result must beTrue—don’t evaluate right side True or expensive_function()→ Never calls function
This is both an optimization and a useful programming pattern for avoiding errors (e.g., x and x.method() won’t fail if x is None).
Did you get it right?
original = [1, 2, 3]
independent = original._____()
independent.append(4).copy() method creates a shallow copy of a list, making it independent from the original. Modifying the copy won’t affect the original. Alternatively, you could use independent = original[:] or independent = list(original)..copy() method creates a shallow copy of a list, making it independent from the original. Modifying the copy won’t affect the original. Alternatively, you could use independent = original[:] or independent = list(original).range() function are correct?range() uses zero-based indexing and excludes the stop value. range(5) gives 0-4, range(2, 7) gives 2-6 (not 7). The third parameter is step size: range(0, 10, 2) gives 0, 2, 4, 6, 8. Modern Python returns a range object (not a list) for memory efficiency.range() uses zero-based indexing and excludes the stop value. range(5) gives 0-4, range(2, 7) gives 2-6 (not 7). The third parameter is step size: range(0, 10, 2) gives 0, 2, 4, 6, 8. Modern Python returns a range object (not a list) for memory efficiency.for num in [1, 2, 3, 4, 5]:
if num % 2 == 0:
continue
print(num, end=' ')continue statement skips the rest of the current iteration and moves to the next one. When num is even (2, 4), it skips the print statement. Only odd numbers (1, 3, 5) are printed.continue statement skips the rest of the current iteration and moves to the next one. When num is even (2, 4), it skips the print statement. Only odd numbers (1, 3, 5) are printed.continue skips to the next iteration.isinstance(3.14, (int, float)) returns True.isinstance() can check against a tuple of types, returning True if the value matches any type in the tuple. Since 3.14 is a float, and float is in the tuple (int, float), it returns True.isinstance() can check against a tuple of types, returning True if the value matches any type in the tuple. Since 3.14 is a float, and float is in the tuple (int, float), it returns True.The Accumulator Pattern
A fundamental programming pattern that builds up a result through iteration:
- Initialize a variable before the loop (e.g.,
total = 0) - Update it inside the loop (e.g.,
total += num) - Use the final result after the loop
Examples:
# Sum accumulator
total = 0
for num in numbers:
total += num
# List accumulator
squares = []
for i in range(1, 6):
squares.append(i ** 2)The key is that the variable is declared outside the loop so it persists across iterations.
Did you get it right?
In the nested loops below, how many times does the inner print statement execute?
for i in range(3):
for j in range(4):
print(i, j)numbers = [1, 2, 3, 4, 5]
for num in numbers:
if num == 3:
print("Found")
break
else:
print("Not found")break, which exits the loop. Since break was called, the else clause is skipped. Only ‘Found’ is printed. The else clause only runs when the loop completes normally without break.break, which exits the loop. Since break was called, the else clause is skipped. Only ‘Found’ is printed. The else clause only runs when the loop completes normally without break.else clause is skipped when break is executed.continue keyword skips the remaining code in the current loop iteration and jumps to the next iteration. It’s different from break, which exits the loop entirely.continue keyword skips the remaining code in the current loop iteration and jumps to the next iteration. It’s different from break, which exits the loop entirely.break or pass.names = ['Alice', 'Bob', 'Charlie']
scores = [85, 92, 78]
for name, score in _____(names, scores):
print(f"{name}: {score}")zip() function takes multiple iterables and returns an iterator of tuples, pairing up elements from each iterable. It’s perfect for parallel iteration over multiple sequences.zip() function takes multiple iterables and returns an iterator of tuples, pairing up elements from each iterable. It’s perfect for parallel iteration over multiple sequences.== and is in Python?== and is in Python?== vs is
== (Equality Operator):
- Compares values
- Checks if two objects have the same content
- Example:
[1, 2, 3] == [1, 2, 3]→True
is (Identity Operator):
- Compares object identity (memory address)
- Checks if two variables reference the exact same object
- Example:
a = [1, 2, 3]; b = [1, 2, 3]; a is b→False
Best Practice:
- Use
isfor singleton objects likeNone:x is None - Use
==for value comparisons
Did you get it right?
You want code to run only when both of these are true:
reason == 'Scheduled'- Either
s_time is Noneorts < s_time
Which condition is correct?
and binds tighter than or, reason == 'Scheduled' and s_time is None or ts < s_time is parsed as (reason == 'Scheduled' and s_time is None) or ts < s_time. This causes the condition to fire whenever ts < s_time, regardless of reason. Explicit parentheses around the or subexpression are required.and binds tighter than or, reason == 'Scheduled' and s_time is None or ts < s_time is parsed as (reason == 'Scheduled' and s_time is None) or ts < s_time. This causes the condition to fire whenever ts < s_time, regardless of reason. Explicit parentheses around the or subexpression are required.and has higher precedence than or—it groups first, just like * before +.