Ручное управление итератором
Создаём итератор из списка и получаем элементы по одному.
numbers = [10, 20, 30]
iterator = iter(numbers)
print(iterator) # <list_iterator object at ...>
print(next(iterator)) # 10
print(next(iterator)) # 20
print(next(iterator)) # 30
print(next(iterator, "end")) # end
Как устроен цикл for внутри
Любой цикл for можно переписать вручную через iter(), next() и обработку StopIteration.
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) # <generator object ...>
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
Практический пример: генерация безопасных паролей
Современная версия решения из практической работы с ранними возвратами и аннотациями типов.
Проверить по документации: использование аннотаций типов,
typing.Iterator и collections.abc.Iterator выходит за рамки исходного материала. Убедитесь, что ваш интерпретатор поддерживает синтаксис tuple[str, ...] (Python 3.9+).
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()
Как запустить в VS Code
- Создайте файл
lesson_54_examples.pyв рабочей папке. - Скопируйте нужный пример из раздела выше.
- Откройте терминал (Ctrl + `).
- Активируйте виртуальное окружение:
venv\Scripts\activate(Windows) илиsource venv/bin/activate(Mac/Linux). - Запустите:
python lesson_54_examples.py.