Типы данных в Python делятся на три группы. Числа: int, float и complex. Одиночные значения: строка str, логический bool и пустое значение None. Коллекции: список list, кортеж tuple, словарь dict, множества set и frozenset. Тип значения показывает функция type(), а в условиях его проверяют через isinstance().
Главное, что стоит запомнить сразу: какие типы изменяемые. Список, словарь и множество меняются на месте, а число, строка и кортеж нет, любая «правка» создаёт новый объект. От этого зависит, что годится в ключи словаря и почему список в двух переменных меняется сразу в обеих.
Ниже каждый тип разобран на коде с реальным выводом Python 3.14. Если вы только начинаете, сначала посмотрите синтаксис Python и статью о том, что такое переменная.
Все встроенные типы Python в одной таблице

В таблице 14 типов, которые встречаются в первые месяцы работы с языком. Колонка «Ключ словаря» показывает, можно ли положить значение в ключ dict или во множество.
| Тип | Что хранит | Пример | Изменяемый | Ключ словаря |
|---|---|---|---|---|
int |
целые числа | 42, -7, 1_000_000 |
нет | да |
float |
дробные числа | 3.14, 2.5e-3 |
нет | да |
complex |
комплексные числа | 3 + 4j |
нет | да |
str |
текст | "питон" |
нет | да |
bool |
истина или ложь | True, False |
нет | да |
NoneType |
«значения нет» | None |
нет | да |
list |
упорядоченный набор | [1, 2, 3] |
да | нет |
tuple |
упорядоченный набор без правок | (1, 2) |
нет | да, если внутри нет списков и словарей |
dict |
пары «ключ: значение» | {"a": 1} |
да | нет |
set |
уникальные значения без порядка | {1, 2} |
да | нет |
frozenset |
неизменяемое множество | frozenset({1, 2}) |
нет | да |
bytes |
последовательность байтов | b"abc" |
нет | да |
bytearray |
изменяемые байты | bytearray(b"abc") |
да | нет |
range |
диапазон целых чисел | range(10) |
нет | да |
Тип любого значения можно посмотреть одной строкой. Атрибут __name__ печатает имя класса без лишних скобок:
values = [42, 3.14, 2 + 3j, "текст", True, None,
[1, 2], (1, 2), {"a": 1}, {1, 2}, frozenset({1}), b"abc", range(3)]
for v in values:
print(type(v).__name__, "→", repr(v))
int → 42
float → 3.14
complex → (2+3j)
str → 'текст'
bool → True
NoneType → None
list → [1, 2]
tuple → (1, 2)
dict → {'a': 1}
set → {1, 2}
frozenset → frozenset({1})
bytes → b'abc'
range → range(0, 3)
Таблица не исчерпывает язык. В стандартной библиотеке есть Decimal для денег, datetime для дат и deque для очередей. А в Python 3.15, который вышел 9 октября 2026 года, появился встроенный неизменяемый словарь frozendict.
Как узнать тип переменной: type() и isinstance()
Python относится к языкам с динамической типизацией. Тип привязан к значению, а не к имени, поэтому одна и та же переменная может сначала хранить число, а потом строку. Узнать, что лежит в переменной сейчас, помогают две функции:
age = 30
print(type(age))
print(type(age) == int)
print(isinstance(age, int))
print(isinstance(True, int))
print(isinstance(3.5, (int, float)))
<class 'int'>
True
True
True
True
type() возвращает класс объекта, её удобно звать в консоли при отладке. Для проверки в условии документация рекомендует isinstance(), потому что эта функция учитывает подклассы. Вторым аргументом можно передать кортеж типов, как в последней строке примера.
Отсюда и сюрприз в четвёртой строке: isinstance(True, int) даёт True. bool в Python считается подтипом int, так прямо записано в справке по встроенным типам. Если в коде нужно отличить число от логического значения, проверяйте bool первым.
Числа: int, float и complex
Числовых типов три, и для повседневных задач хватает первых двух. Деление / всегда даёт float, даже когда числа делятся нацело, а целую часть от деления возвращает //. Остальные знаки собраны в статье об операторах Python.
Целые числа: int
Целые числа в Python не ограничены по размеру: в справке сказано, что у них неограниченная точность. Поэтому 2 ** 100 считается без переполнения:
print(2 ** 100)
print(7 / 2, 7 // 2)
print(6 / 2, type(6 / 2))
1267650600228229401496703205376
3.5 3
3.0 <class 'float'>
Методы int, работа с большими числами и типовые задачи вроде проверки на чётность разобраны в отдельной статье о типе int.
Дробные числа: float
Дробную часть пишут через точку. Запятая превращает запись в кортеж из двух целых чисел, и Python не выдаёт никакой ошибки. Хранится float в двоичном виде, поэтому часть десятичных дробей записана приблизительно:
price = 3,14
print(price, type(price))
print(0.1 + 0.2)
print(0.1 + 0.2 == 0.3)
import math
print(math.isclose(0.1 + 0.2, 0.3))
from decimal import Decimal
print(Decimal("0.1") + Decimal("0.2"))
print(round(2.5), round(3.5))
(3, 14) <class 'tuple'>
0.30000000000000004
False
True
0.3
2 4
Так устроена двоичная арифметика с плавающей точкой в любом языке, в учебнике Python ей отведена целая глава. Дробные числа сравнивают через math.isclose(), а деньги считают в Decimal и передают значения строкой, как в примере.
Ещё одна ловушка в последней строке. round() округляет половину до чётного, поэтому round(2.5) даёт 2, а round(3.5) даёт 4. Округление всегда вверх разобрано в статье про math.ceil.
Комплексные числа: complex
Мнимую часть обозначают буквой j. Тип нужен в инженерных расчётах и обработке сигналов, в аналитике и веб-разработке он почти не встречается.
z = 3 + 4j
print(z.real, z.imag, abs(z))
3.0 4.0 5.0
Строки: тип str
Строка в Python — неизменяемая последовательность символов Unicode. Индексы и срезы работают как у списка, а вот заменить символ по индексу нельзя:
word = "питон"
print(word[0], word[-1], len(word))
print(word.upper(), word)
print("П" + word[1:])
word[0] = "П"
п н 5
ПИТОН питон
Питон
TypeError: 'str' object does not support item assignment
Метод upper() вернул новую строку, а исходная осталась прежней. Поэтому результат методов строк сохраняют в переменную: word = word.upper().
Пятнадцать самых нужных методов собраны в шпаргалке по строкам. Как вставить переменную в текст и отформатировать число, рассказывает статья про f-строки.
bool и None: логический тип и «пустое» значение
У bool два значения, True и False. Раз это подтип int, в арифметике они ведут себя как 1 и 0. Этим пользуются, чтобы посчитать, сколько элементов прошли проверку: sum() по списку из True и False вернёт число истинных.
Проверить в if можно любое значение. Ложью считаются None, False, ноль любого числового типа и пустые последовательности и коллекции. Всё остальное истинно, включая строку "False":
print(True + True)
print(sum([True, False, True]))
for v in [0, 0.0, "", [], {}, None, "0", "False", [0]]:
print(repr(v), "→", bool(v))
2
2
0 → False
0.0 → False
'' → False
[] → False
{} → False
None → False
'0' → True
'False' → True
[0] → True
Общая логика истины и лжи, короткое замыкание and и or и сравнение с другими языками есть в статье о логическом типе boolean.
None означает «значения нет». Его возвращает функция без return или функция, которая ничего не нашла:
def find_user(name):
if name == "Аня":
return {"name": "Аня", "age": 25}
result = find_user("Олег")
print(result)
print(result is None)
None
True
С None сравнивают через is, а не ==: так рекомендует PEP 8. Чем is отличается от обычного сравнения, разобрано в статье про оператор !=.
Коллекции: list, tuple, dict и set

Коллекция хранит несколько значений сразу. Выбор зависит от двух вопросов: важен ли порядок и будут ли данные меняться после создания.
| Тип | Порядок | Повторы | Меняется | Когда брать |
|---|---|---|---|---|
list |
есть | можно | да | набор, который растёт и меняется: строки файла, заказы |
tuple |
есть | можно | нет | фиксированная запись: координаты, строка таблицы |
dict |
по порядку добавления | ключи уникальны | да | поиск по ключу: номер заказа → данные заказа |
set |
нет | нет | да | убрать дубли, быстро проверить «есть ли элемент» |
Порядок ключей словаря гарантирован с Python 3.7: в справке прямо сказано, что словари сохраняют порядок добавления. У множества порядка нет, и печатать его стоит через sorted(), если результат нужно сравнивать.
По каждой коллекции у нас есть подробный разбор с ошибками новичков:
- списки в Python: создание, методы, копии;
- кортеж: чем отличается от списка и где удобен;
- словари и метод get(): как достать значение без KeyError;
- множества: пересечение, разность и frozenset.
Изменяемые и неизменяемые типы данных
Переменная в Python хранит ссылку на объект, а не сам объект. Пока объект неизменяемый, это незаметно. Со списком и словарём разница видна с первой строки:
a = [1, 2, 3]
b = a
b.append(4)
print(a)
s = "кот"
t = s
t += "ик"
print(s, t)
nums = [1, 2]
before = id(nums)
nums += [3]
print(id(nums) == before)
point = (1, 2)
before = id(point)
point += (3,)
print(id(point) == before)
[1, 2, 3, 4]
кот котик
True
False
Что произошло в каждом из четырёх блоков:
b = aне копирует список. Обе переменные ссылаются на один объект, иappend()черезbпоменялa. Копию делают явно:b = a.copy().- Со строкой такого не бывает:
t += "ик"собрал новую строку, а вsосталось «кот». - Для списка
+=дописал элементы в тот же объект, поэтомуidне изменился. - Для кортежа тот же оператор создал новый кортеж с другим
id: старый поменять нельзя.
Почему список нельзя сделать ключом словаря
Словарь и множество ищут элементы по хешу. По определению из глоссария Python, у хешируемого объекта хеш никогда не меняется в течение его времени жизни. Ключом может быть только хешируемое значение: число, строка, кортеж из хешируемых элементов. Список изменяемый, и Python его не пустит:
prices = {(55.75, 37.61): "Москва"}
print(prices[(55.75, 37.61)])
bad = {[55.75, 37.61]: "Москва"}
Москва
TypeError: cannot use 'list' as a dict key (unhashable type: 'list')
В Python 3.12 текст ошибки короче: TypeError: unhashable type: 'list'.
Решение в обеих версиях одно: превратить список в кортеж, tuple([55.75, 37.61]).
Изменяемое значение по умолчанию
Классическая ошибка с изменяемым типом связана со списком в параметре функции. В учебнике Python это вынесено в «Важное предупреждение»: значение параметра по умолчанию вычисляется только один раз. Все вызовы функции получают один и тот же список:
def add_item(item, basket=[]):
basket.append(item)
return basket
print(add_item("хлеб"))
print(add_item("молоко"))
def add_item_ok(item, basket=None):
if basket is None:
basket = []
basket.append(item)
return basket
print(add_item_ok("хлеб"))
print(add_item_ok("молоко"))
['хлеб']
['хлеб', 'молоко']
['хлеб']
['молоко']
Во второй функции правильный приём: по умолчанию None, а новый список создаётся внутри при каждом вызове. Как устроены параметры и возврат значения, подробно рассказано в статье о функциях в Python.
Преобразование типов

Значение переводят в другой тип функцией с именем этого типа: int(), float(), str(), list(). Сам Python строку и число не смешивает, их сначала приводят к одному типу.
print(int("42") + 1)
print(int(3.99), int(-3.99))
print(float("3.5"))
print(str(2026) + " год")
print(list("abc"), tuple([1, 2]), set([1, 1, 2]))
print(bool("False"))
print(float("3,5"))
43
3 -3
3.5
2026 год
['a', 'b', 'c'] (1, 2) {1, 2}
True
ValueError: could not convert string to float: '3,5'
Четыре вывода из этого примера:
int()не округляет, а отбрасывает дробную часть в сторону нуля: из 3.99 получится 3, из −3.99 получится −3.float()понимает только точку. Число с запятой из русской таблицы сначала чистят:float(s.replace(",", ".")).bool("False")равноTrue, потому что строка непустая. Ответ «да» или «нет» сравнивают со строкой, а не приводят кbool.list(),tuple()иset()принимают любую последовательность, аset()по пути убирает повторы.
Функция input() всегда возвращает строку, поэтому ввод чисел с клавиатуры начинается с int(input()). Как при этом не уронить программу на кривом вводе, разобрано в статье про ввод чисел.
Типы Python в pandas: что видит аналитик
У колонок таблицы pandas свои типы, их называют dtype. Они похожи на питоновские, но называются иначе, и одна разница регулярно портит расчёты:
import pandas as pd
df = pd.DataFrame({
"id": [1, 2, 3],
"price": [199.0, 250.5, 99.9],
"city": ["Москва", "Казань", "Пермь"],
"paid": [True, False, True],
})
print(df.dtypes)
ages = pd.Series([25, None, 31])
print(ages.tolist(), ages.dtype)
ages_int = pd.Series([25, None, 31], dtype="Int64")
print(ages_int.tolist(), ages_int.dtype)
print(type(df.loc[0, "id"]))
id int64
price float64
city str
paid bool
dtype: object
[25.0, nan, 31.0] float64
[25, <NA>, 31] Int64
<class 'numpy.int64'>
Как читать этот вывод (pandas 3.1):
intв колонке становитсяint64,floatпревращается вfloat64, аboolтак и остаётсяbool.- Строки с pandas 3.0 получают отдельный тип str. В pandas 2.x та же колонка показывалась как
object, и в старом коде такие проверки ещё встречаются. - Один пропуск превращает колонку целых чисел в float64. Пропуск pandas обозначает через NaN, а NaN относится к числам с плавающей точкой. Идентификаторы после этого выглядят как 25.0.
- Тип с большой буквы,
dtype="Int64", хранит целые числа и пропуск<NA>вместе. - Отдельное значение, взятое из таблицы, имеет тип
numpy.int64, а не питоновскийint.
С чего начать работу с библиотекой, рассказывает статья про pandas для новичка. Как устроены файлы, из которых обычно читают таблицы, объясняет разбор формата CSV.
Частые ошибки с типами данных
Пять ситуаций, которые новичок встречает чаще других, и что в каждой делать.
TypeError: can only concatenate str (not "int") to str
age = 30
print("Мне " + age + " лет")
TypeError: can only concatenate str (not "int") to str
Строку склеили с числом. Решение: f-строка f"Мне {age} лет" или явное str(age).
ValueError: invalid literal for int() with base 10
print(int("3.5"))
ValueError: invalid literal for int() with base 10: '3.5'
В int() передали строку, в которой не целое число: дробь, «12 руб.» или пустую строку после Enter.
Решение: дробь переводить в два шага, int(float("3.5")), лишние символы убирать, а пользовательский ввод оборачивать в try и except.
TypeError: 'str' object does not support item assignment
Попытка поменять символ строки по индексу. Решение: собрать новую строку срезом, "П" + word[1:], как в разделе о строках, или методом replace().
Сравнение дробных чисел через ==
0.1 + 0.2 == 0.3 даёт False. Решение: math.isclose() для сравнения и Decimal для денег, оба показаны в разделе о float.
Список сам поменялся в другой переменной
Вместо копии написали b = a. Решение: a.copy() для плоского списка и copy.deepcopy(a) для вложенного. Ещё четыре похожие ловушки собраны в статье о списках.
Где освоить Python системно
Типы данных открывают любой курс по Python, дальше идут функции, классы, файлы и библиотеки. Короткую карту этих тем с примерами кода даёт статья об основах программирования, а порядок изучения на год вперёд расписан в плане, как стать Python-разработчиком.
Если хотите пройти путь с проверкой заданий и обратной связью, сравните программы в каталоге курсов по Python:
| Курс | Школа | Стоимость со скидкой | В рассрочку | Длительность | Обзор курса от Checkroi |
|---|---|---|---|---|---|
| Профессия «Python-разработчик» Перейти на сайт курса | 157 335 ₽ | 5987 ₽/мес. | 10 месяцев | Обзор курса | |
| Fullstack-разработчик на Python Перейти на сайт курса | 137 000 ₽ | 7125 ₽/мес. | 21 месяц | Обзор курса | |
| ДО Профессия Python-разработчик Перейти на сайт курса | 149 001 ₽ | 3167 ₽/мес. | 10 месяцев | Обзор курса | |
| Автоматизированное тестирование на Python Перейти на сайт курса | 118 754 ₽ | 4108 ₽/мес. | 9 месяцев | Обзор курса | |
| Профессия Python-разработчик Перейти на сайт курса | 140 040 ₽ | 3890 ₽/мес. | 10 месяцев | Обзор курса |
Больше программ — в полном каталоге курсов по Python




