Типы данных в Python для начинающих: какие бывают и как с ними работать
Готовимся к собеседованию на должность Python-разработчика. Знакомимся с системой типов в Python, встроенными типами данных и правилами работы с ними.


Иллюстрация: Оля Ежак для Skillbox Media
Python — объектно-ориентированный язык программирования, его основу составляют объекты и классы. Объект — это область памяти компьютера, которая описывается типом (он же класс) и значением. При этом от типа зависит область значений объекта, операции и методы, которые к нему можно применять.
Python предоставляет богатый набор встроенных типов данных. Поэтому при решении стандартных задач питонист реже пишет собственные классы, чем, например, разработчик на Java.
Из этой статьи вы узнаете:
- что такое строгая динамическая типизация в Python;
- что такое изменяемые и неизменяемые типы данных;
- какие встроенные типы данных есть в Python;
- что почитать про типы данных в Python.
Что такое строгая динамическая типизация
Python — язык программирования со строгой динамической типизацией.
«Строгая» означает, что язык не производит неявные преобразования типов и не создаёт сюрпризов при их случайном смешении.
Чтобы понять, о чём идёт речь, запустите этот код на Python и JavaScript, а затем сравните результаты:
#классический пример из JavaScript
some_number = 1 + '1'
JavaScript любезно выдаст строку '11', а Python выругается такой фразой:
TypeError: unsupported operand type (s) for +: 'int' and 'str'
Можно подумать, что JavaScript лучше, чем Python, — ведь он даёт больше свободы разработчикам. Но не всё так однозначно: в больших скриптах, на 3–5 тысяч строк, такая свобода может сыграть злую шутку. Например, если банковская программа вместо 100 + 100 = 200 долларов спишет со счёта 100100 :)
К счастью, в Python такой трюк не пройдёт. Строгий интерпретатор забьёт тревогу и не позволит разработчику смешать типы.
«Динамическая» означает, что типы объектов определяются в процессе исполнения программы (runtime). Поэтому питонисты могут не указывать типы переменных. Переменные в Python — это всего лишь указатели на объекты, они не содержат информации о типе.
Вы можете создавать и изменять переменные в любой момент, главное — присвойте значение:
#год рождения — целое число 1995
year_of_birth = 1995
print(year_of_birth)
#заменили на строку «nineteen ninety five»
year_of_birth = "nineteen ninety five"
print(year_of_birth)
А вот в языках со статической типизацией, таких как C++, C# и Java, типы объектов определяются ещё на этапе компиляции. Поэтому при попытке запустить такой код, например, в C++ компилятор выдаст ошибку:
«невозможно преобразовать „const char [20]“ в „int“»
Придётся объявлять новую переменную:
int main()
{
int year_of_birth{ 5 };
std::cout << year_of_birth << std::endl;
//создадим новую переменную str_year_of_birth
string str_year_of_birth {"nineteen ninety five"};
std::cout << str_year_of_birth << std::endl;
return 0;
}
Мы оставим детальное сравнение статической и динамической типизации для другой статьи. На практике и та, и другая имеют свои плюсы и минусы.

Читайте также:
Изменяемые и неизменяемые типы данных
Типы данных в Python можно разделить на изменяемые и неизменяемые.
Когда мы присваиваем новое значение неизменяемому объекту, Python не перезаписывает его, а создаёт новый объект с тем же именем. Чтобы в этом убедиться, достаточно проверить id — уникальный номер, который присваивается каждому объекту в Python:
#числовые типы в Python — неизменяемые
int_obj = 10
print("id of int_obj: ", id(int_obj)) #140717895746096
int_obj += 5
print("id of int_obj: ", id(int_obj)) #140717895746256
Когда мы прибавляем 5 к переменной int_obj, на её месте создаётся новый объект с тем же именем. Заметьте: при первом выводе id равен 140717895746096, а после выполнения операции сложения — 140717895746256.
А вот идентификатор списка list_obj не меняется, потому что списки в Python — это изменяемые объекты:
#а объекты типа list — изменяемые
list_obj = [10, 20, 30]
print("id of list_obj: ", id(list_obj)) #2302150079496
list_obj += [40]
print("id of list_obj: ", id(list_obj)) #2302150079496
К неизменяемым объектам относятся числа, строки и кортежи, а к изменяемым — списки, словари и множества. Это свойство нужно учитывать при передаче объектов в функцию. Например, если вы не хотите, чтобы функция изменила исходный список, передайте в неё копию этого списка.
Теперь рассмотрим встроенные типы данных языка Python.
Какие встроенные типы данных есть в Python
В недрах интерпретатора Python зашито много типов данных. Их можно разделить на три группы:
- Простые — числа и строки.
- Коллекции — списки, кортежи и словари.
- Остальные — файлы, итераторы, сокеты, NaN.
Отдавайте предпочтение встроенным типам. Они упрощают разработку и более эффективны, чем пользовательские классы, потому что представляют собой оптимизированные структуры данных на языке C.
Числа
Программы на Python умеют работать с целыми числами (int), числами с плавающей точкой (float) и комплексными числами (complex). В целом числовые объекты в Python поддерживают те же операции, что и числа в других языках программирования:
a = 20.5
b = 10
#сложение
sum_ab = a + b
print(sum_ab) #результат: 30.5
#умножение
mult_ab = a * b
print(mult_ab) #результат: 205
#деление
div_ab = a / b
print(div_ab) #результат: 2.05
Также в стандартной библиотеке Python есть модуль math, который подключается директивой import math, — он содержит широкий набор функций для работы с числовыми данными:
import math
a = 20.5
b = 10
#факториал числа b
math_factor = math.factorial(b)
print(math_factor) #результат: 3628800
#посчитать остаток от деления a на b
math_fmod = math.fmod(a, b)
print(math_fmod) #результат:0.5
#отсечь дробную часть у числа a
math_trunc = math.trunc(a)
print(math_trunc) #результат: 20
А теперь получим какое-нибудь очень большое число. Например, возведём 27 в 560-ю степень:
print(27 ** 560)
#результат:
#366191221537348906724224962113233696161029018222927370716739871087661400220838310915248021370798668687237512226282332116... и так далее
Для таких объектов в Python есть специальный тип — long. Но если в том же C++ самый большой тип long long ограничен 64 битами (самое большое положительное число равно 18 446 744 073 709 551 615), то «длинные числа» в Python не ограничены.
Читайте также:
Строки
Строки (string) — это последовательности символов, поэтому к ним применимы многие методы других последовательностей: списков и кортежей. Например, обращение к элементу по индексу, вычисление количества символов, конкатенация и получение среза.
Рассмотрим основные операции со строками в Python:
first_str = 'skill'
second_str = 'box'
#конкатенация строк
some_string = first_str + second_str
print(some_string) #skillbox
#длина строки
length = len(some_string)
print(length) #8
#первый символ строки
first_symbol = some_string[0]
print(first_symbol) #s
#срез строки с первого по пятый символ
skill_slice = some_string[0:5]
print(skill_slice) #skill
Строки поддерживают работу с отрицательными индексами. Их удобно использовать, когда нужно обратиться к элементу с конца:
#последний символ строки
last_symbol = some_string[-1]
print(last_symbol) #x
#последние три символа строки 'skillbox'
box_slice = some_string[-3:]
print(box_slice) #box
Кроме того, у типа string есть ряд методов, уникальных для него:
#поиск подстроки
#если подстрока найдена, метод вернёт позицию её первого элемента, если нет — вернёт -1
ill_substr = some_string.find('ill')
print(ill_substr)
#поиск подстроки с заменой, заменим skill на school
school_box = some_string.replace('skill', 'school')
print(school_box) #schoolbox
#разбить строку по разделителю
student_name = 'Ivan_Ivanovich_Petrov'
list_of_substr = student_name.split('_')
print(list_of_substr) #['Ivan', 'Ivanovich', 'Petrov']
Списки
Список (list) — это упорядоченная коллекция объектов. Списки могут иметь сколько угодно уровней вложенности и хранить неограниченное количество объектов. Кроме того, в одном списке могут одновременно храниться объекты разных типов.
Над списками можно производить те же операции, что и над строками:
some_list = ['s', 'k', 'i', 'l', 'l', 'b', 'o', 'x']
#первый символ списка
list_first_symbol = some_list[0]
print(list_first_symbol) #s
#срез списка с первого по пятый элемент
list_slice = some_list[0:5]
print(list_slice) #['s', 'k', 'i', 'l', 'l']
#последний элемент списка
list_last_symbol = some_list[-1]
print(list_last_symbol) #x
Но у списков есть и специфические методы, которые присущи только им. Например, можно добавить новый элемент в конце списка, удалить i-й элемент или отсортировать список:
#добавить новый элемент в конец списка
some_list.append('!')
print(some_list) #['s', 'k', 'i', 'l', 'l', 'b', 'o', 'x', '!']
#удалить элемент с индексом 3
some_list.pop(3)
print(some_list) #'s', 'k', 'i', 'l', 'b', 'o', 'x', '!']
#отсортировать элементы списка в порядке возрастания
some_list.sort()
print(some_list) #['!', 'b', 'i', 'k', 'l', 'o', 's', 'x']
Кортежи
Кортежи (tuple) — это те же списки, только неизменяемые. Над ними можно производить те же операции, что и над списками, — кроме тех, которые изменяют кортеж:
some_tuple = ('p', 'y', 't', 'h', 'o', 'n')
#последний элемент кортежа
last_element = some_tuple[-1]
print(last_element)
#срез кортежа с первого по третий элемент
tuple_slice = some_tuple[0:3]
print(tuple_slice)
#меняем значение первого элемента
some_tuple[0] = 'c'
При попытке заменить элемент 'p' на 'c' Python выдаст сообщение об ошибке:
TypeError: 'tuple' object does not support item assignment
Вы спросите: зачем нужны кортежи, когда есть списки с более широким набором методов и операций? Как мы уже сказали выше, иногда программистам важно быть уверенными, что функция не изменит значение объекта. Как раз для таких случаев и годятся кортежи.
Словари
Словарь (dict) — это неупорядоченная коллекция пар «ключ — значение». В качестве ключей могут выступать любые неизменяемые объекты (числа, строки и даже кортежи).
Получать доступ к элементам, удалять и создавать новые довольно просто:
#словарь с данными об ученике Skillbox
some_dict = {'first_name':'Алексей',
'age':35, 'is_paid':True,
'courses':['python', 'javascript', 'html/css'], }
print(some_dict)
#элемент с ключом 'last_name'
print(some_dict['first_name']) # 'Алексей'
#создать элемент, присвоив значение несуществующему ключу
some_dict['second_name'] = 'Петров'
print(some_dict)
#{'first_name': 'Алексей', 'age': 35, 'is_paid': True, 'courses': ['python', 'javascript', 'html/css'], 'second_name': 'Петров'}
del some_dict['is_paid']
print(some_dict)
#{'first_name': 'Алексей', 'age': 35, 'courses': ['python', 'javascript', 'html/css'], 'second_name': 'Петров'}
В качестве значений словарь может хранить объекты совершенно разных типов — даже другие словари. Глубина вложенности не ограничена.
Так как словари являются отображениями, а не последовательностями, то элементы в них не упорядочены. Это значит, что при выводе элементов в цикле for их порядок не всегда будет совпадать с порядком, заданным при инициализации словаря.
Файлы
Объекты-файлы позволяют работать с файловой системой компьютера. Чтобы создать такой объект, нужно передать функции open имя файла и режим доступа (чтение или запись).
Допустим, вы собрались написать книгу о Python. Тогда нужно создать файловый объект в режиме записи — w write, а затем записывать в него строки текста с помощью метода write ():
#начнём с первой главы
#создадим файл с книгой в текущей папке
my_book = open("my_book.txt", 'w')
my_book.write('Chapter 1: Hello, Python!\n')
my_book.write('To be continued...\n')
#закроем поток записи
my_book.close()
А теперь проверим, всё ли сохранилось как надо. Для этого создадим новый объект-файл с помощью той же функции open, но в режиме чтения — r read:
#откроем нашу книгу и проверим содержимое
book = open("my_book.txt", 'r')
text = book.read()
print(text)
Как вы можете убедиться, все строки, которые мы записали в файл, на месте.
Для закрепления — небольшая шпаргалка по базовым типам в Python:

Что почитать про типы данных в Python
Теперь вы знаете о типах в Python достаточно, чтобы решать простейшие задачи и даже ответить на вопросы на собеседовании. Если хотите узнать о системе типов ещё больше — почитайте классические источники:
- «Изучаем Python 3», Часть II. Типы и операции, М. Лутц;
- «Программирование на Python 3», Глава 2. Типы данных, М. Саммерфилд;
- документацию Python, раздел «Built-in Types».
Больше интересного про код в нашем телеграм-канале. Подписывайтесь!