← Назад к вопросам
Как определить, является ли объект массивом?
1.3 Junior🔥 181 комментариев
#Python Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как определить, является ли объект массивом
В Python нет встроенного типа "массив" как в других языках. Есть список (list), но также есть другие типы похожих структур. Рассмотрю различные способы проверки.
1. Проверка на список (list)
Самый распространённый случай — проверка что это обычный список.
# Способ 1: isinstance() — рекомендуется
obj = [1, 2, 3]
if isinstance(obj, list):
print('Это список')
# Способ 2: type()
if type(obj) == list:
print('Это список')
# Способ 3: __class__
if obj.__class__.__name__ == 'list':
print('Это список')
# isinstance() предпочтительнее, т.к. работает с наследованием
class MyList(list):
pass
my_obj = MyList([1, 2, 3])
print(isinstance(my_obj, list)) # True
print(type(my_obj) == list) # False
2. Проверка на "array-like" объекты
В Python много объектов похожих на массив: list, tuple, range, numpy array, pandas Series.
import collections.abc
import numpy as np
def is_array_like(obj):
"""Проверяет что объект похож на массив/последовательность"""
return isinstance(obj, collections.abc.Sequence)
print(is_array_like([1, 2, 3])) # True
print(is_array_like((1, 2, 3))) # True
print(is_array_like(range(5))) # True
print(is_array_like(np.array([1, 2, 3]))) # True
print(is_array_like("string")) # True (строка тоже Sequence!)
print(is_array_like({1, 2, 3})) # False (set не Sequence)
print(is_array_like({'a': 1})) # False (dict не Sequence)
3. Проверка на итерируемость
Если нужно проверить что объект можно итерировать (но не строка):
import collections.abc
def is_iterable_not_string(obj):
"""Проверяет итерируемость, но исключает строки"""
return isinstance(obj, collections.abc.Iterable) and not isinstance(obj, str)
print(is_iterable_not_string([1, 2, 3])) # True
print(is_iterable_not_string((1, 2, 3))) # True
print(is_iterable_not_string({1, 2, 3})) # True
print(is_iterable_not_string({'a': 1})) # True (dict итерируемый)
print(is_iterable_not_string("string")) # False
print(is_iterable_not_string(42)) # False
4. Проверка на NumPy array
import numpy as np
obj = np.array([1, 2, 3])
# Способ 1: isinstance
if isinstance(obj, np.ndarray):
print('Это NumPy array')
# Способ 2: hasattr (проверяем атрибуты)
if hasattr(obj, 'shape') and hasattr(obj, 'dtype'):
print('Это похоже на NumPy array')
# Способ 3: type
if type(obj).__module__ == 'numpy':
print('Это NumPy объект')
5. Проверка на размерность (1D, 2D и т.д.)
import numpy as np
def is_1d_array(obj):
"""Проверяет что это одномерный массив"""
if isinstance(obj, (list, tuple)):
return True
if isinstance(obj, np.ndarray):
return obj.ndim == 1
return False
def is_2d_array(obj):
"""Проверяет что это двумерный массив"""
if isinstance(obj, list):
return all(isinstance(row, (list, tuple)) for row in obj)
if isinstance(obj, np.ndarray):
return obj.ndim == 2
return False
print(is_1d_array([1, 2, 3])) # True
print(is_1d_array([[1, 2], [3, 4]])) # False
print(is_2d_array([[1, 2], [3, 4]])) # True
print(is_2d_array(np.array([[1, 2], [3, 4]]))) # True
print(is_2d_array(np.array([1, 2, 3]))) # False
6. Проверка с типизацией (Type Hints)
from typing import List, Sequence, Iterable, Union, Any
import numpy as np
from collections.abc import Sequence as ABCSequence
def process_list(items: List[int]) -> int:
"""Функция ожидает именно список целых чисел"""
if not isinstance(items, list):
raise TypeError(f'Ожидается list, получен {type(items).__name__}')
return sum(items)
def process_sequence(items: Sequence[int]) -> int:
"""Функция ожидает любую последовательность"""
if not isinstance(items, ABCSequence) or isinstance(items, str):
raise TypeError(f'Ожидается Sequence, получен {type(items).__name__}')
return sum(items)
def process_array(items: Union[List, np.ndarray]) -> float:
"""Может быть list или NumPy array"""
if isinstance(items, np.ndarray):
return float(items.mean())
elif isinstance(items, list):
return sum(items) / len(items)
else:
raise TypeError(f'Ожидается list или ndarray')
print(process_list([1, 2, 3])) # 6
print(process_sequence((1, 2, 3))) # 6
print(process_array(np.array([1, 2, 3, 4]))) # 2.5
7. Утиная типизация (Duck Typing)
Вместо проверки типа проверяем наличие нужных методов:
def is_list_like(obj):
"""Проверяет что объект ведёт себя как список"""
# Должны быть методы для индексации и итерации
return hasattr(obj, '__getitem__') and hasattr(obj, '__iter__')
def is_array_like_v2(obj):
"""Более строгая проверка — нужны индексация, длина и итерация"""
return (
hasattr(obj, '__getitem__') and
hasattr(obj, '__len__') and
hasattr(obj, '__iter__')
)
class CustomArray:
def __init__(self, data):
self.data = list(data)
def __getitem__(self, index):
return self.data[index]
def __len__(self):
return len(self.data)
def __iter__(self):
return iter(self.data)
obj = CustomArray([1, 2, 3])
print(is_array_like_v2(obj)) # True
8. Полезная функция с обработкой разных типов
import numpy as np
from typing import Union, List, Tuple
def normalize_array(obj: Union[List, Tuple, np.ndarray]) -> np.ndarray:
"""
Преобразует различные типы массивов в NumPy array
"""
# Проверяем тип
if isinstance(obj, np.ndarray):
return obj
elif isinstance(obj, (list, tuple)):
return np.array(obj)
elif isinstance(obj, str):
raise TypeError('Строка не может быть преобразована в массив')
elif hasattr(obj, '__array__'):
# Объект поддерживает __array__ protocol
return np.asarray(obj)
else:
raise TypeError(f'Не могу преобразовать {type(obj).__name__} в массив')
# Использование
print(normalize_array([1, 2, 3])) # array([1, 2, 3])
print(normalize_array((1, 2, 3))) # array([1, 2, 3])
print(normalize_array(np.array([1, 2, 3]))) # array([1, 2, 3])
print(normalize_array(CustomArray([1, 2, 3]))) # array([1, 2, 3])
9. Практичная функция для обработки
import collections.abc
import numpy as np
from typing import Any
def is_array(obj: Any, strict: bool = False) -> bool:
"""
Проверяет является ли объект массивом/последовательностью
Args:
obj: объект для проверки
strict: если True, исключает строки; если False, включает
Returns:
bool: True если это массив/последовательность
"""
# Исключаем строки всегда если strict=True
if strict and isinstance(obj, (str, bytes)):
return False
# Проверяем основные типы
if isinstance(obj, (list, tuple)):
return True
# Проверяем NumPy
if isinstance(obj, np.ndarray):
return True
# Проверяем Sequence из abc
if not strict and isinstance(obj, collections.abc.Sequence):
return True
# Проверяем если есть методы для индексации
if (
hasattr(obj, '__getitem__') and
hasattr(obj, '__len__') and
hasattr(obj, '__iter__')
):
return True
return False
# Тесты
print(is_array([1, 2, 3])) # True
print(is_array((1, 2, 3))) # True
print(is_array(np.array([1, 2, 3]))) # True
print(is_array(range(5))) # True
print(is_array('string', strict=False)) # True
print(is_array('string', strict=True)) # False
print(is_array({1, 2, 3})) # False
print(is_array(42)) # False
Рекомендации
- Для обычных списков: используй
isinstance(obj, list) - Для любых последовательностей:
isinstance(obj, collections.abc.Sequence)(исключи строки!) - Для NumPy:
isinstance(obj, np.ndarray) - Для type hints: используй
List[T],Sequence[T],Union[List, Tuple] - Duck typing: лучше проверяй методы чем тип, если работаешь с абстрактными интерфейсами
- В production: всегда исключай строки из проверки на array-like