Explain the difference between is and ==. Then explain what b = a, b = a.copy() and b = copy.deepcopy(a) each do when a = [[1, 2], [3, 4]].
Show the explanation
`==` compares values. `is` compares identity.
a == bcallsa.__eq__(b): do the two objects hold equal values?a is basks whether both names refer to the same object in memory (id(a) == id(b)).- Use
isonly for singletons:x is None,x is True. Never use it to compare numbers or strings.x is 1000can be False even whenx == 1000. CPython caches small integers (−5 to 256) and some strings, soissometimes seems to work, but that is an implementation detail. Python 3.8+ warns aboutisused with a literal.
Three ways to "copy" `a = [[1, 2], [3, 4]]`
| Code | New outer list? | New inner lists? | After b[0].append(9), is a changed? |
|---|---|---|---|
b = a | no (same object) | no | yes |
b = a.copy() / a[:] / list(a) / copy.copy(a) | yes (shallow copy) | no; the inner lists are shared | yes |
b = copy.deepcopy(a) | yes | yes, recursively | no |
With a shallow copy, b.append([5]) does not affect a, but changes inside the shared inner lists do.
Deep copy details: deepcopy remembers the objects it has already copied (a memo dict), so it handles shared references and cycles. It is slower, and some objects (open files, locks) cannot be deep-copied. Classes can customise copying with __copy__ and __deepcopy__.
Rule of thumb: for a list of immutable values such as numbers or strings, a shallow copy is enough. For nested mutable structures, such as a matrix or a list of dicts, use deepcopy or rebuild the structure explicitly: [row[:] for row in grid].
Original UniCircle question. Last reviewed 22 Oct 2026.
