Appearance
Итераторы
Итератор — это объект, который позволяет перебирать элементы коллекции (например, списка или кортежа) по одному за раз. Итераторы используются для экономии памяти и повышения эффективности работы с большими наборами данных.
Итераторы необходимы, когда нужно обрабатывать элементы коллекции по одному, без загрузки всей коллекции в память. Например, при чтении большого файла или обходе элементов базы данных.
Итераторы реализуются работой двух функций:
iter()
: Возвращает сам итератор. Это метод, который возникает при организации итераций, например, в цикле for
.next()
: Возвращает следующий элемент в последовательности. Если элементы закончились, вызывается исключение StopIteration
.
Пример использования функций iter()
и next()
. Когда элементы коллекции заканчиваются, метод __next__()
вызывает исключение StopIteration
.:
python
numbers = [1, 2, 3]
iterator = iter(numbers)
print(iterator)
print(next(iterator)) # 1
print(next(iterator)) # 2
print(next(iterator)) # 3
print(next(iterator)) # StopIteration
Пример с использованием while
:
python
numbers = [1, 2, 3, 4, 5]
iterator = iter(numbers)
while True:
try:
number = next(iterator)
except StopIteration:
break
else:
print(number)
Пример с использованием for
:
python
numbers = [1, 2, 3, 4, 5]
for number in iter(numbers):
print(number)
Встроенные функции, такие как max()
и min()
могут принимать один аргумент итератора и возвращать наибольший или наименьший элемент. Операторы in
и not in
также поддерживают итераторы: x in iterator
возвращает True
, если x
найден в потоке, возвращаемом итератором.
Вы столкнетесь с очевидными проблемами, если итератор бесконечен:
max()
иmin()
, никогда ничего не вернет,- и если элемент
x
никогда не закончиться в потоке,in
иnot in
операторы также ничего не вернут.
Обратите внимание, что вы можете двигаться только вперед в итераторе: нет способа получить предыдущий элемент, сбросить итератор или сделать его копию. Объекты итератора могут опционально предоставлять эти дополнительные возможности, но протокол итератора определяет только метод __next__()
. Поэтому функции могут потреблять весь вывод итератора, и если вам нужно сделать что-то другое с тем же потоком, вам придется создать новый итератор.
python
numbers = [1, 2, 3, 4, 5]
iter_numbers = iter(numbers)
print('\n1 iteration:', end=' ')
for number in iter_numbers:
print(number, end=', ')
print('\n2 iteration:', end=' ')
for number in iter_numbers:
print(number, end=', ')
iter_numbers = iter(numbers)
print('\n3 iteration:', end=' ')
for number in iter_numbers:
print(number, end=', ')
В результат выполнения 2 итератор будет пустым, так как он уже выполнился в предыдущем цикле. Но если итератор создать заново, то можно продолжит итерации:
1 iteration: 1, 2, 3, 4, 5,
2 iteration:
3 iteration: 1, 2, 3, 4, 5,
Зачем нужны итераторы?
Итераторы полезны в следующих случаях:
- Эффективность памяти: Они позволяют обрабатывать данные по одному элементу за раз, что снижает потребление памяти.
- Универсальность: Итераторы предоставляют единый интерфейс для работы с различными коллекциями и типами данных.
- Ленивые вычисления: Итераторы позволяют производить вычисления по требованию, не загружая все данные в память сразу.
Когда используются итераторы?
- Чтение файлов: Вы можете использовать итераторы для чтения файлов построчно, что особенно полезно для работы с большими файлами.
- Работа с потоками данных: Итераторы удобны для обработки потоков данных, таких как данные из сетевых запросов или генераторов данных.
- Обработка больших данных: Они позволяют работать с большими наборами данных, загружая в память только необходимые части.
Упражнения:
- Создайте список из строк и используйте итератор для вывода каждого элемента.
- Создайте список чисел от 1 до 10 и используйте итератор для вывода только четных чисел.
- Создайте строку с именами людей, разделенными запятыми. Используйте итератор для вывода только имен, начинающихся с буквы "И".
- Напишите функцию, которая принимает итерируемый объект и возвращает список всех его элементов, используя итератор.
- Напишите функцию, которая принимает строку и возвращает список всех уникальных символов в ней, используя итератор.
- Напишите функцию, которая принимает на вход список и возвращает его элементы в обратном порядке, используя итератор и
next()
.
Типы данных, поддерживающие итераторы
В Python многие встроенные типы данных поддерживают итераторы, включая:
- Строки (
str
) - Списки (
list
) - Кортежи (
tuple
) - Словари (
dict
) - Множества (
set
)
Пример использования итераторов с различными типами данных:
python
# string - строка
word = "hello"
for char in word:
print(char)
# list - список
numbers = [1, 2, 3]
for number in numbers:
print(number)
# tuple - кортеж
letters = ('a', 'b', 'c')
for letter in letters:
print(letter)
# dictionary - словарь
fruits = {'apple': 1, 'banana': 2}
for key in fruits:
print(key, fruits[key])
# set - множество
unique_numbers = {1, 2, 3}
for number in unique_numbers:
print(number)
Обратите внимание, что начиная с Python 3.7, порядок итерации словаря гарантированно совпадает с порядком вставки. В более ранних версиях поведение не было определено и могло различаться между реализациями.
Применение iter()
к словарю всегда проходит по ключам, но у словарей есть методы, которые возвращают другие итераторы. Если вы хотите выполнить итерацию по значениям или парам ключ/значение
, вы можете явно вызвать методы values()
или items()
чтобы получить соответствующий итератор.
Конструктор dict()
может принимать итератор, который возвращает конечный поток кортежей: (key, value)
python
list_tuple_country_capitals = [
('Brazil', 'Brasilia'),
('Russia', 'Moscow'),
('India', 'New Delhi'),
('China', 'Beijing'),
('South Africa', 'Pretoria, Cape Town, Bloemfontein')
]
print(dict(iter(list_tuple_country_capitals)))
print(dict(list_tuple_country_capitals))
Упражнения:
- Напишите программу, которая принимает строку и выводит каждый символ на новой строке, используя итератор.
- Создайте словарь и используйте итератор для вывода всех ключей и значений.
- Создайте словарь с именами и возрастами людей. Используйте итератор для вывода только имен людей, которым более 30 лет.
- Создайте итератор, который генерирует первые n чисел Фибоначчи. Реализуйте это без использования классов.
- Используя функцию
iter()
, создайте бесконечный итератор, который поочередно возвращает элементы из списка [10, 20, 30].