✅ Решения заданий

⚠️ Рекомендация: попробуйте решить задания самостоятельно, прежде чем смотреть ответы.

Решение задания 1

Ответ: c, d.

Итератор использует __iter__() и __next__() и создаётся через iter(iterable). Он не хранит все элементы и не предназначен для многократного использования.

Решение задания 2

Ответ: a, c.

StopIteration возникает, когда итератор исчерпан, и его можно перехватить через try-except или избежать с помощью значения по умолчанию в next().

Решение задания 3

Ответ: b — на экран выведется только 5, 10, 15.

После первого цикла for итератор оказывается исчерпан, поэтому второй цикл не выполняется.

Решение задания 4

Ответ: a — A, B, C, A.

itertools.cycle бесконечно повторяет последовательность, поэтому четвёртый вызов next() возвращает первый элемент снова.

Решение задания 5

Ответ: a, c.

Генераторное выражение записывается в круглых скобках, не хранит все элементы и исчерпывается после одного прохода.

Решение задания 6 — генерация паролей

from itertools import permutations
from string import ascii_lowercase, ascii_uppercase, digits

ALL_CHARS = list(ascii_lowercase + ascii_uppercase + digits)


def is_valid(password: tuple[str, ...]) -> bool:
    chars = "".join(password)

    has_lower = any(ch in ascii_lowercase for ch in chars)
    has_upper = any(ch in ascii_uppercase for ch in chars)
    has_digit = any(ch in digits for ch in chars)

    if not (has_lower and has_upper and has_digit):
        return False

    for i in range(len(chars) - 1):
        if abs(ord(chars[i]) - ord(chars[i + 1])) == 1:
            return False

    return True


def main() -> None:
    all_variants = permutations(ALL_CHARS, 4)
    valid_passwords = ("".join(variant) for variant in all_variants if is_valid(variant))

    with open("valid_passwords.txt", "w", encoding="utf-8") as file:
        file.write("\n".join(valid_passwords))


if __name__ == "__main__":
    main()

Логика решения: permutations создаёт ленивый итератор всех вариантов длины 4. Генераторное выражение фильтрует их через is_valid, не создавая огромного промежуточного списка. Функция is_valid использует ранние возвраты: как только одно из условий нарушено, проверка останавливается.

Решение задания 7

total = sum(x ** 2 for x in range(20) if x % 2 == 0)
print(total)  # 1140

Логика решения: генераторное выражение отбирает чётные числа, возводит их в квадрат и передаёт по одному в sum(). Промежуточный список не создаётся.