Код
#статьи

Типы данных в Python для начинающих: какие бывают и как с ними работать

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

Иллюстрация: Оля Ежак для Skillbox Media

Python — объектно-ориентированный язык программирования, его основу составляют объекты и классы. Объект — это область памяти компьютера, которая описывается типом (он же класс) и значением. При этом от типа зависит область значений объекта, операции и методы, которые к нему можно применять.

Python предоставляет богатый набор встроенных типов данных. Поэтому при решении стандартных задач питонист реже пишет собственные классы, чем, например, разработчик на Java.

Из этой статьи вы узнаете:


Что такое строгая динамическая типизация

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:

Изображение: Skillbox Media

Что почитать про типы данных в Python

Теперь вы знаете о типах в Python достаточно, чтобы решать простейшие задачи и даже ответить на вопросы на собеседовании. Если хотите узнать о системе типов ещё больше — почитайте классические источники:

  • «Изучаем Python 3», Часть II. Типы и операции, М. Лутц;
  • «Программирование на Python 3», Глава 2. Типы данных, М. Саммерфилд;
  • документацию Python, раздел «Built-in Types».

Больше интересного про код в нашем телеграм-канале. Подписывайтесь!

Проверьте свой английский. Бесплатно ➞
Нескучные задания: small talk, поиск выдуманных слов — и не только. Подробный фидбэк от преподавателя + персональный план по повышению уровня.
Пройти тест
Понравилась статья?
Да

Пользуясь нашим сайтом, вы соглашаетесь с тем, что мы используем cookies 🍪

Ссылка скопирована