Вы обходите список users и хотите, чтобы i был индексом, а u — значением, без использования range(len(users)). Какой вариант подходит лучше всего?

Afor u in users: i = users.index(u): ищет индекс через .index() на каждой итерации
Bfor i, u in enumerate(users): print(i, u): enumerate() сразу даёт пару индекс и значение
Cfor i in range(len(users)): u = users[i]: ручная работа с длиной и индексами вместо итерации
Dfor i, u in zip(users, range(len(users))): print(i, u): индекс и значение перепутаны местами
Правильный ответ. enumerate() даёт индекс и элемент в одной итерации и не требует ручной работы с длиной и индексами.

Разбор

enumerate(users) читабельнее и безопаснее, чем range(len(users)): возвращает пару (индекс, элемент) напрямую. Вариант с users.index(u) даёт неверные индексы при дубликатах и работает за квадратичное время. В варианте с zip(users, range(len(users))) аргументы перепутаны местами — i будет значением, а u — индексом.

Проверь себя · 1/3разбор после ответа
Есть списки пользователей и трат: users = ['u1', 'u2'] и spends = [100, 200]. После d = {}, в цикле for u, s in zip(users, spends): выполняется d[u] = s. Чему равно d['u2']?
Тренировать Python в Telegram

Ещё вопросы по теме «Циклы и условия»