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

Как определить, является ли объект массивом?

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
Как определить, является ли объект массивом? | PrepBro