В отладке вы сделали pairs = zip(users, spends), затем debug = list(pairs). После этого d = dict(pairs) оказался пустым. Почему?

AПотому что zip() возвращает iterator, и list(pairs) его полностью исчерпало.
BПотому что dict() не умеет принимать результат zip().
CПотому что zip() сортирует данные и удаляет пары.
DПотому что нужно писать pairs = zip(spends, users).
Правильный ответ. zip() в Python 3 возвращает одноразовый итератор; любые операции, которые его «вычитывают», делают его пустым для повторного использования.

Разбор

Объект из zip(users, spends) хранит позицию в потоке пар. Когда вы вызываете list(pairs), он перебирается до конца (внутри через next()), и теперь в pairs уже нет элементов. Поэтому dict(pairs) получает пустой итератор и создаёт пустой словарь. Решение: материализовать один раз (pairs_list = list(zip(...))) или заново вызвать zip(users, spends) для второго прохода.

Проверь себя · 1/3разбор после ответа
Что создаёт выражение squares = (x * x for x in xs)?
Тренировать Python в Telegram

Ещё вопросы по теме «Итераторы и генераторы»