Перебор и преобразование
Для обычного прохода коллекции используйтеfor value in values. Если нужен индекс, enumerate(values) возвращает пары индекс–значение. zip связывает элементы нескольких последовательностей и по умолчанию заканчивается на самой короткой. Если длины должны совпасть, проверьте их или используйте strict=True в подходящей версии Python.
List comprehension создаёт список: [x * x for x in values if x > 0]. Сначала фильтруется элемент, затем вычисляется выражение. Не помещайте в comprehension сложную логику с несколькими побочными эффектами: обычный цикл легче проверить.
Итератор
Итерируемый объект позволяет получить итератор через iter.next берёт следующий элемент, а StopIteration сообщает об окончании. Цикл for выполняет эту обработку за вас. Итератор может быть одноразовым: после исчерпания он не возвращается к началу автоматически.
Генераторная функция использует yield. Выполнение останавливается на очередном значении и продолжается при следующем запросе. Генераторное выражение (x * x for x in values) тоже вычисляет значения по мере запроса. Это полезно для большого потока, когда весь результат сразу не нужен.
Цена ленивости
Генератор экономит память результата, но не устраняет стоимость вычислений и не делает бесконечный источник конечным. Вызов list загрузит весь поток в память. Для повторного прохода создайте новый генератор либо заранее решите, что результат нужно сохранить.В примере сумма потребляет все три значения. После этого список из того же генератора пуст: новых значений у него больше нет.