""" Урок 54. Итераторы и генераторные выражения — весь код примеров одним файлом. Источник: subjects/python-fundamentals/course/lessons/54-iterators-generators/examples.html Файл собран автоматически (tools/build_lesson_examples.py): правьте страницу урока. Запуск: python lesson-54.py """ # ==================================================================== # Ручное управление итератором # ==================================================================== numbers = [10, 20, 30] iterator = iter(numbers) print(iterator) # print(next(iterator)) # 10 print(next(iterator)) # 20 print(next(iterator)) # 30 print(next(iterator, "end")) # end # ==================================================================== # Как устроен цикл for внутри # ==================================================================== numbers = [10, 20, 30] iterator = iter(numbers) while True: try: num = next(iterator) print(num) except StopIteration: break # ==================================================================== # Примеры из модуля itertools # ==================================================================== import itertools # Бесконечный счётчик counter = itertools.count(start=1, step=10) print(next(counter), next(counter), next(counter)) # 1 11 21 # Бесконечное повторение cycler = itertools.cycle(["A", "B", "C"]) print(next(cycler), next(cycler), next(cycler), next(cycler)) # A B C A # Объединение коллекций merged = itertools.chain([1, 2, 3], [100, 200, 300]) print(list(merged)) # [1, 2, 3, 100, 200, 300] # Декартово произведение pairs = itertools.product([1, 2], ["A", "B"]) print(list(pairs)) # [(1, 'A'), (1, 'B'), (2, 'A'), (2, 'B')] # Перестановки letters = ["A", "B", "C"] print(list(itertools.permutations(letters, 2))) # [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')] # ==================================================================== # Генераторные выражения # ==================================================================== import sys # Генераторное выражение squares = (x ** 2 for x in range(5)) print(squares) # print(list(squares)) # [0, 1, 4, 9, 16] # Повторно использовать уже нельзя print(list(squares)) # [] # ==================================================================== # Сравнение памяти: список vs генератор # ==================================================================== import sys list_comp = [x ** 2 for x in range(10 ** 6)] gen_expr = (x ** 2 for x in range(10 ** 6)) print("List:", sys.getsizeof(list_comp), "bytes") print("Generator:", sys.getsizeof(gen_expr), "bytes") # ==================================================================== # Генераторы в any() и all() # ==================================================================== words = ["apple", "Banana", "cherry", "Apricot"] has_upper = any(word[0].isupper() for word in words) all_long = all(len(word) > 3 for word in words) print(has_upper) # True print(all_long) # True # ==================================================================== # Практический пример: генерация безопасных паролей # ==================================================================== from itertools import permutations from string import ascii_lowercase, ascii_uppercase, digits from collections.abc import Iterator 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 generate_passwords() -> Iterator[str]: """Генерирует подходящие пароли длиной 4 символа.""" all_variants = permutations(ALL_CHARS, 4) return ("".join(variant) for variant in all_variants if is_valid(variant)) def main() -> None: valid_passwords = generate_passwords() with open("valid_passwords.txt", "w", encoding="utf-8") as file: file.write("\n".join(valid_passwords)) if __name__ == "__main__": main()