GotchaDifficulty: Intermediate2 min

Pointing curr.next Backwards Before Saving It

Flip the arrow first and the only reference to the rest of the list is gone: the loop ends after one node and the other nodes are lost.

Setting curr.next = prev before saving curr.next loses the rest of the list, because that reference was the only way to reach the next node. The four lines look interchangeable, and the first two are the ones most often swapped: after the swap, the line meant to save the next node saves prev instead. On 8 1 6 the first pass points 8 at null, then reads 8's next, now null, so the loop ends after one node.

The arrow flipped before saving it, and after

wrong_order.pypy
class ListNode:
    def __init__(self, val):
        self.val = val
        self.next = None


def build(values):
    head = None
    for val in reversed(values):
        node = ListNode(val)
        node.next = head
        head = node
    return head


def values_of(head):
    values = []
    while head:
        values.append(head.val)
        head = head.next
    return values


def reverse(head):
    prev = None
    curr = head
    while curr:
        curr.next = prev
        next_node = curr.next
        prev = curr
        curr = next_node
    return prev


print("reversed:", *values_of(reverse(build([8, 1, 6]))))
OutputRan with python:3.14.8-slim-trixie (Python 3.14.8)
reversed: 8
right_order.pypy
class ListNode:
    def __init__(self, val):
        self.val = val
        self.next = None


def build(values):
    head = None
    for val in reversed(values):
        node = ListNode(val)
        node.next = head
        head = node
    return head


def values_of(head):
    values = []
    while head:
        values.append(head.val)
        head = head.next
    return values


def reverse(head):
    prev = None
    curr = head
    while curr:
        next_node = curr.next
        curr.next = prev
        prev = curr
        curr = next_node
    return prev


print("reversed:", *values_of(reverse(build([8, 1, 6]))))
OutputRan with python:3.14.8-slim-trixie (Python 3.14.8)
reversed: 6 1 8

The first version returns a list holding only 8, and no error is raised: 1 and 6 still exist, but nothing refers to them, so they are lost, and Python's garbage collector frees them. The fix is the order: save next_node = curr.next first, while it still points forward, and only then turn the arrow. A test on a list of one node passes with either order, which is how the mistake survives; any list of two or more nodes shows it.