На какие направления делятся типы данных в Python?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Классификация типов данных в Python
Типы данных в Python делятся на несколько направлений в зависимости от различных критериев классификации. Разберём основные подходы.
1. По изменяемости (Mutability)
Это одна из самых важных классификаций в Python.
Неизменяемые типы (Immutable)
Могут быть изменены (перезаписаны), но сам объект не меняется — создаётся новый:
# int, float, complex
x = 5
x = 10 # Создаётся новый объект, старый забывается
# str (строки)
text = "Hello"
text = text + " World" # Новая строка, старая неизменна
# tuple (кортежи)
t = (1, 2, 3)
t = (1, 2, 3, 4) # Новый кортеж
# frozenset (неизменяемое множество)
fs = frozenset([1, 2, 3])
fs = frozenset([1, 2, 3, 4]) # Новый frozenset
# bool
flag = True
flag = False # Новое значение
# None
value = None
value = 42 # Новое значение
# bytes
b = b"hello"
b = b"world" # Новая байт-строка
Почему это важно:
# Неизменяемые типы безопасны как ключи словаря
d = {}
t = (1, 2, 3)
d[t] = "value" # OK
# Нельзя с изменяемыми типами
list_key = [1, 2, 3]
d[list_key] = "value" # TypeError: unhashable type: 'list'
Изменяемые типы (Mutable)
Можно менять без создания нового объекта:
# list (списки)
my_list = [1, 2, 3]
my_list.append(4) # Тот же объект, изменён
my_list[0] = 999 # Тот же объект, изменён
# dict (словари)
my_dict = {'a': 1}
my_dict['b'] = 2 # Тот же объект, изменён
del my_dict['a'] # Тот же объект, изменён
# set (множества)
my_set = {1, 2, 3}
my_set.add(4) # Тот же объект, изменён
my_set.remove(1) # Тот же объект, изменён
# bytearray (изменяемая байт-строка)
ba = bytearray(b"hello")
ba[0] = ord('H') # Тот же объект, изменён
# Пользовательские классы (обычно изменяемы)
class User:
def __init__(self, name):
self.name = name
user = User("John")
user.name = "Jane" # Тот же объект, изменён
Практический пример проблемы изменяемости:
# Опасно с изменяемыми параметрами по умолчанию
def add_item(item, lst=[]): # ОПАСНО!
lst.append(item)
return lst
result1 = add_item(1) # [1]
result2 = add_item(2) # [1, 2] ← Неожиданно!
# Правильно:
def add_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
result1 = add_item(1) # [1]
result2 = add_item(2) # [2]
2. По скалярности (Scalarity)
Скалярные типы (Scalar)
Представляют одно значение:
# Числовые
int_val = 42
float_val = 3.14
complex_val = 1 + 2j
# Строки
str_val = "Hello"
# Логические
bool_val = True
# Пустое значение
none_val = None
# Байты
bytes_val = b"data"
Составные типы (Collection/Composite)
Содержат несколько значений:
# Упорядоченные (порядок важен)
list_val = [1, 2, 3] # Изменяемый список
tuple_val = (1, 2, 3) # Неизменяемый кортеж
str_val = "abc" # Строка (последовательность символов)
range_val = range(1, 4) # Диапазон чисел
deque_val = deque([1, 2, 3]) # Двусторонняя очередь
# Неупорядоченные (порядок не важен)
set_val = {1, 2, 3} # Изменяемое множество (уникальные значения)
frozenset_val = frozenset({1, 2, 3}) # Неизменяемое множество
# Ассоциативные (ключ-значение)
dict_val = {'a': 1, 'b': 2} # Словарь
3. По назначению (Purpose)
Числовые типы
int # Целые числа: 42, -1, 0
float # С плавающей точкой: 3.14, -2.5
complex # Комплексные: 1+2j, 3j
decimal # Высокая точность (из модуля decimal)
Текстовые типы
str # Unicode строки: "Hello"
bytes # Байт-строки: b"data"
bytearray # Изменяемые байт-строки
Логические типы
bool # Истина/Ложь: True, False
NoneType # Пустое значение: None
Последовательные типы (Sequences)
str # Последовательность символов
bytes # Последовательность байт
list # Последовательность элементов
tuple # Неизменяемая последовательность
range # Последовательность чисел
deque # Двусторонняя последовательность
Множества (Sets)
set # Изменяемое множество
frozenset # Неизменяемое множество
Картирование (Mapping)
dict # Словарь (наиболее распространённый)
defaultdict # Словарь с значениями по умолчанию
OrderedDict # Упорядоченный словарь (Python < 3.7)
Counter # Счётчик элементов
ChainMap # Несколько словарей как один
4. По способу хранения (Memory Layout)
Атомарные типы
# Хранятся как отдельное значение в памяти
int x = 5
float y = 3.14
bool z = True
Ссылочные типы (Reference Types)
# Переменная хранит ссылку (адрес) на объект в памяти
my_list = [1, 2, 3] # Переменная → адрес в памяти → список
my_dict = {'a': 1} # Переменная → адрес в памяти → словарь
# Поэтому присваивание не копирует:
list1 = [1, 2, 3]
list2 = list1 # list2 указывает на тот же объект
list2.append(4) # list1 тоже изменился! [1, 2, 3, 4]
# Нужна копия:
list3 = list1.copy() # Неглубокая копия
list4 = copy.deepcopy(list1) # Глубокая копия
5. По иерархии (Type Hierarchy)
object (всё является объектом)
├── type (метакласс)
├── int, float, complex (числа)
├── str, bytes (текст)
├── bool (логика)
├── NoneType
├── list, tuple (последовательности)
├── dict (картирование)
├── set, frozenset (множества)
├── range
├── function
├── class
└── Custom classes
Проверка типа:
type(42) # <class 'int'>
type(3.14) # <class 'float'>
type([1, 2, 3]) # <class 'list'>
# isinstance — более правильный способ
isinstance(42, int) # True
isinstance([1, 2], (list, tuple)) # True
isinstance(42, (int, float)) # True
6. По сложности (Complexity)
Простые (Primitive)
int, float, bool, str, bytes, None
Составные (Container)
list, dict, set, tuple, frozenset
Специальные
function, class, generator, coroutine, module
7. По типизации в контексте Python
Динамически типизированные
# Тип определяется во время выполнения
x = 5 # int
x = "hello" # str (теперь это string)
x = [1, 2] # list (теперь это list)
# Никакой ошибки — Python позволяет
Статическое аннотирование (Type Hints)
# Python 3.5+: опциональные аннотации типов
def greet(name: str) -> str:
return f"Hello, {name}!"
age: int = 25
users: list[dict[str, int]] = [
{"name": "John", "age": 30},
{"name": "Jane", "age": 25},
]
# Это не меняет поведение Python, только помощь для type checker
# Используй mypy для проверки:
# mypy script.py
Практическая таблица
| Тип | Изменяемый | Упорядоченный | Уникальные | Хешируемый | Пример |
|---|---|---|---|---|---|
| int | ❌ | - | - | ✅ | 42 |
| str | ❌ | ✅ | ❌ | ✅ | "Hello" |
| list | ✅ | ✅ | ❌ | ❌ | [1, 2, 3] |
| tuple | ❌ | ✅ | ❌ | ✅ | (1, 2, 3) |
| dict | ✅ | ✅ | ❌ | ❌ | {'a': 1} |
| set | ✅ | ❌ | ✅ | ❌ | {1, 2, 3} |
| frozenset | ❌ | ❌ | ✅ | ✅ | frozenset({1, 2}) |
Когда что использовать
# Нужна неизменяемость?
data = (1, 2, 3) # tuple, не list
keys = frozenset([...]) # frozenset, не set
# Нужна быстрота поиска?
if item in my_set: # set, не list (O(1) vs O(n))
pass
# Нужен порядок + уникальные значения?
from collections import OrderedDict
orders = OrderedDict() # В Python 3.7+ обычный dict сохраняет порядок
# Нужны высокие требования к точности?
from decimal import Decimal
price = Decimal('19.99') # Не float для денег!
# Нужны динамические значения по умолчанию?
from collections import defaultdict
counts = defaultdict(int) # Вместо dict + проверок
Вывод
Типы данных в Python классифицируются по нескольким направлениям:
- Изменяемость — неизменяемые (int, str, tuple) vs изменяемые (list, dict, set)
- Скалярность — скалярные (одно значение) vs составные (коллекции)
- Назначение — числовые, текстовые, логические, последовательные, множества, картирование
- Память — атомарные vs ссылочные
- Иерархия — по наследованию от object
- Сложность — примитивные vs составные
- Типизация — динамическая (по умолчанию) vs статическая (аннотации)
Ключевой навык: понимать различия и выбирать правильный тип для каждой задачи.