These questions ask you to trace what names refer to, distinguish rebinding from mutation, and reason about common built-in types. The reliable approach is to follow names and objects separately instead of imagining each variable as a permanently typed box.
Trace the operation before naming the type
Assignment evaluates the expression on the right, then binds the name on the left to the resulting object. A later assignment may bind that name to an object of another type; it does not convert the earlier object. Try score = 7 followed by score = 'high': the name simply changes what it refers to.
For multiple assignment, obtain every right-hand value before rebinding any target. For chained assignment, evaluate the right-hand expression once and bind every target to that same object. This difference matters when the shared object is mutable. Try first = second = list(): changing the list through either name is visible through the other.
| Signal | Method |
|---|---|
| A change to a list or dictionary | Ask whether the existing object changes; these types are mutable. |
| A new integer, float, Boolean, string or None | Treat the value as immutable; a name may be rebound, but the existing object does not change in place. |
| An exact-class question | Use type; its result is a class object. |
| A class-family question | Use isinstance; instances of subclasses satisfy the check. |
Remember three special boundaries. Boolean is a subclass of integer, and converting the true Boolean to integer produces one. None is the sole instance of NoneType and is normally checked with identity. Python integers grow beyond fixed machine-word ranges while memory permits, whereas binary floats can only approximate many decimal fractions.
Conversions obey the syntax expected by the target type. Try int('27'): the text has integer form, so conversion succeeds. Text containing a decimal point is not an integer literal for direct conversion with int and raises ValueError.
Reject the tempting wrong routes
| Trap | How to reject it |
|---|---|
| Treating the first assignment as a permanent type declaration | Python attaches the type to the object. Reassignment can make the same name refer to a different kind of object. |
| Updating swap targets from left to right | Capture all right-hand values first; otherwise one old value would be lost, which is not Python's multiple-assignment model. |
| Assuming chained assignment constructs a fresh mutable object for each name | Count evaluations of the constructor. One evaluation creates one object shared by all targets. |
| Using type as though it included subclasses | Choose type for exact class and isinstance for membership in a class hierarchy. Do not compare class-name text. |
| Expecting int to parse any numeric-looking text | Check the literal form inside the string. A decimal-point form is not silently rounded or truncated by direct string-to-integer conversion. |
Try it
For Python variables and types, which statements correctly classify mutability? Select all that apply.
- A list is mutable.
- An integer changes in place when its name is reassigned.
- A dictionary is mutable.
- A string is a mutable sequence of characters.
Which result pair is produced by `isinstance(True, int)` and `int(True)`?
- `False` and `0`
- `False` and `1`
- `True` and a TypeError
- `True` and `1`
Why can a calculation with the float `0.1` show a tiny discrepancy from the expected decimal result?
- Python randomly changes the final decimal digit.
- Binary float cannot represent every decimal fraction exactly.
- A float always performs integer division before storage.
- The value is exact, so any discrepancy must be a display bug.