← Назад к вопросам

Какие типы данных в Python итерируемые?

1.0 Junior🔥 181 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Какие типы данных в Python итерируемые

Это базовый, но важный вопрос. Многие разработчики используют итерацию интуитивно, но не знают точно какие типы итерируемы и почему. Это знание критично для написания гибкого и надёжного кода.

1. Что такое итерируемость

Объект итерируем (iterable) если он:

  1. Реализует метод __iter__(), который возвращает итератор
  2. Итератор реализует методы __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!

Какие типы данных в Python итерируемые? | PrepBro