Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Какие типы данных в Python итерируемые
Это базовый, но важный вопрос. Многие разработчики используют итерацию интуитивно, но не знают точно какие типы итерируемы и почему. Это знание критично для написания гибкого и надёжного кода.
1. Что такое итерируемость
Объект итерируем (iterable) если он:
- Реализует метод
__iter__(), который возвращает итератор - Итератор реализует методы
__iter__()и__next__()
# Общее определение
class Iterable:
def __iter__(self):
"""Возвращает итератор"""
return Iterator()
class Iterator:
def __iter__(self):
"""Возвращает сам себя"""
return self
def __next__(self):
"""Возвращает следующее значение или raise StopIteration"""
raise StopIteration
# Проверить итерируемость
from collections.abc import Iterable as IterableABC
print(isinstance([1, 2, 3], IterableABC)) # True
print(isinstance(42, IterableABC)) # False
2. Встроенные итерируемые типы
2.1 Последовательности
# ✅ list — список
for item in [1, 2, 3]:
print(item)
# ✅ tuple — кортеж
for item in (1, 2, 3):
print(item)
# ✅ str — строка (итерирует символы)
for char in "hello":
print(char) # h, e, l, l, o
# ✅ bytes — байты
for byte in b"hello":
print(byte) # 104, 101, 108, 108, 111
# ✅ bytearray — изменяемый bytes
for byte in bytearray(b"hello"):
print(byte)
# ✅ range — диапазон чисел
for i in range(5):
print(i) # 0, 1, 2, 3, 4
2.2 Множества
# ✅ set — множество
for item in {1, 2, 3}:
print(item) # Порядок не гарантирован
# ✅ frozenset — неизменяемое множество
for item in frozenset([1, 2, 3]):
print(item)
2.3 Словари
# ✅ dict — словарь (итерирует ключи)
for key in {"a": 1, "b": 2}:
print(key) # a, b
# Итерирование значений
for value in {"a": 1, "b": 2}.values():
print(value) # 1, 2
# Итерирование элементов
for key, value in {"a": 1, "b": 2}.items():
print(key, value) # a 1, b 2
2.4 Специальные итерируемые
# ✅ zip — объединение итерируемых
for a, b in zip([1, 2, 3], ['a', 'b', 'c']):
print(a, b) # 1 a, 2 b, 3 c
# ✅ map — применение функции
for result in map(str.upper, ['a', 'b', 'c']):
print(result) # A, B, C
# ✅ filter — фильтрация
for item in filter(lambda x: x > 2, [1, 2, 3, 4]):
print(item) # 3, 4
# ✅ enumerate — индекс и элемент
for idx, item in enumerate(['a', 'b', 'c']):
print(idx, item) # 0 a, 1 b, 2 c
# ✅ reversed — в обратном порядке
for item in reversed([1, 2, 3]):
print(item) # 3, 2, 1
# ✅ iter() — создать итератор
iterator = iter([1, 2, 3])
print(next(iterator)) # 1
print(next(iterator)) # 2
3. НИТЕРИРУЕМЫЕ типы
# ❌ int — число
try:
for item in 42:
print(item)
except TypeError as e:
print(f"Ошибка: {e}") # 'int' object is not iterable
# ❌ float — дробное число
try:
for item in 3.14:
print(item)
except TypeError as e:
print(f"Ошибка: {e}")
# ❌ bool — логический
try:
for item in True:
print(item)
except TypeError as e:
print(f"Ошибка: {e}")
# ❌ None
try:
for item in None:
print(item)
except TypeError as e:
print(f"Ошибка: {e}") # 'NoneType' object is not iterable
4. Кастомные итерируемые классы
4.1 Простой пример
class CountUp:
"""Итерируемый класс, который считает от 1 до n"""
def __init__(self, n):
self.n = n
def __iter__(self):
"""Вернуть итератор"""
return CountUpIterator(self.n)
class CountUpIterator:
"""Итератор для CountUp"""
def __init__(self, n):
self.n = n
self.current = 0
def __iter__(self):
"""Вернуть сам себя"""
return self
def __next__(self):
"""Вернуть следующее значение или остановиться"""
if self.current < self.n:
self.current += 1
return self.current
else:
raise StopIteration
# Использование
for num in CountUp(3):
print(num) # 1, 2, 3
4.2 Использование generator (проще)
def count_up(n):
"""Генератор — более простой способ создать итерируемое"""
current = 0
while current < n:
current += 1
yield current
for num in count_up(3):
print(num) # 1, 2, 3
# Генератор ЛЕГЧЕ чем явная реализация __iter__/__next__
4.3 Встроенный метод iter
class Fibonacci:
"""Класс с встроенным методом __iter__"""
def __init__(self, max):
self.max = max
def __iter__(self):
"""Вернуть объект итератора"""
self.a, self.b = 0, 1
return self
def __next__(self):
"""Генерировать следующее число Фибоначчи"""
if self.a > self.max:
raise StopIteration
value = self.a
self.a, self.b = self.b, self.a + self.b
return value
for fib in Fibonacci(10):
print(fib) # 0, 1, 1, 2, 3, 5, 8
5. Проверка итерируемости
from collections.abc import Iterable, Iterator
# Проверить итерируемость
def process(obj):
if isinstance(obj, Iterable):
for item in obj:
print(item)
else:
print(f"{obj} не итерируем")
process([1, 2, 3]) # Работает
process("hello") # Работает
process(42) # Ошибка: не итерируем
# Проверить является ли объект итератором
it = iter([1, 2, 3])
print(isinstance(it, Iterator)) # True
print(isinstance([1, 2, 3], Iterator)) # False (это Iterable, но не Iterator)
6. Различие между Iterable и Iterator
from collections.abc import Iterable, Iterator
# Iterable: имеет __iter__, но не обязательно __next__
list_obj = [1, 2, 3]
print(isinstance(list_obj, Iterable)) # True
print(isinstance(list_obj, Iterator)) # False
# Iterator: имеет оба __iter__ и __next__
iterator = iter([1, 2, 3])
print(isinstance(iterator, Iterable)) # True
print(isinstance(iterator, Iterator)) # True
# Правило: Итератор ВСЕГДА итерируем, но не наоборот
print(iter([1, 2, 3]) is iter([1, 2, 3])) # False (новые итераторы)
print(iter(iterator) is iterator) # True (итератор возвращает сам себя)
7. Практические ошибки
7.1 Неправильное использование generator
# ❌ Проблема: generator исчерпывается
def my_gen():
yield 1
yield 2
yield 3
gen = my_gen()
list1 = list(gen) # [1, 2, 3]
list2 = list(gen) # [] (generator уже исчерпан!)
# ✅ Решение: создать новый generator
gen = my_gen()
list1 = list(gen)
gen = my_gen() # Новый generator
list2 = list(gen)
7.2 Модификация во время итерации
# ❌ ОПАСНО: изменение list во время итерации
my_list = [1, 2, 3, 4, 5]
for item in my_list:
if item % 2 == 0:
my_list.remove(item) # RuntimeError или неправильный результат!
# ✅ Правильно: создать копию
my_list = [1, 2, 3, 4, 5]
for item in my_list[:]:
if item % 2 == 0:
my_list.remove(item)
7.3 Итерирование None
# ❌ Частая ошибка
def get_items():
if some_condition:
return None
return [1, 2, 3]
for item in get_items(): # Может быть TypeError если None
print(item)
# ✅ Правильно: всегда возвращай list
def get_items():
if some_condition:
return []
return [1, 2, 3]
for item in get_items():
print(item)
8. Типы по категориям
Встроенные итерируемые
# Последовательности
list, tuple, str, bytes, bytearray, range
# Множества
set, frozenset
# Словари
dict
# Специальные
zip, map, filter, enumerate, reversed, iter(), range()
# Файловые объекты
with open('file.txt') as f:
for line in f: # Файл итерируем
print(line)
Встроенные НИТЕРИРУЕМЫЕ
# Числовые типы
int, float, complex, Decimal, Fraction
# Логические
bool
# Спецтипы
None, type, function
Чек-лист
- Списки, кортежи, строки — итерируемы
- Словари итерируют ключи (по умолчанию)
- Числа (int, float) НЕ итерируемы
- None НЕ итерируем
- Generator — итерируем
- Для кастомного класса: реализуй
__iter__()и__next__() - Generator проще чем явная реализация
- Различай Iterable (has iter) и Iterator (has iter and next)
Best Practice
- Используй generator функции для простых итерируемых
- Проверяй итерируемость перед использованием:
isinstance(obj, Iterable) - Не меняй список во время итерации (создай копию)
- Помни про None — может быть нитерируем в неожиданный момент
- Type hints:
Iterable[str]для функций принимающих итерируемое
Итерируемость — одна из самых мощных особенностей Python. Овладей этим — овладеешь Python!