Справочник по Python · модуль 1 · данные и имена
Глава 1.2
Типы данных
в Python
В прошлой главе переменная получила имя и значение. Теперь разберёмся с самим значением: какого оно рода, что с ним разрешено делать и почему "10" и 10 — это два разных значения, с которыми программа поступает по-разному.
- Категория
- Синтаксис и базовые концепции
- Уровень
- Начальный
- Связанные темы
- Переменные, ввод данных, условия
- Зачем это знать
- Понимать, какие операции допустимы над значением и почему возникает TypeError
§1Что такое тип данных
Тип данных определяет две вещи: какие значения может хранить переменная и какие операции над этими значениями допустимы. Число можно разделить, строку — повторить. Сложить строку с числом нельзя: операция + для такой пары типов не определена.
В Python тип не объявляют заранее. Он определяется автоматически, в момент присваивания, по самому значению — такой подход называется динамической типизацией.
x = 10 # int — целое число y = 3.14 # float — число с дробной частью name = "Alice" # str — строка
Проверить тип можно встроенной функцией type(). Она пригодится, когда программа ведёт себя не так, как вы ожидали: чаще всего причина в том, что в переменной лежит значение не того типа.
print(type(x)) # <class 'int'> print(type(y)) # <class 'float'> print(type(name)) # <class 'str'>
В Python одной переменной можно по очереди присваивать значения разных типов. После x = 10 функция type(x) покажет int, а после x = "десять" — str. Язык это разрешает, но читать такой код сложнее, поэтому обычно в одной переменной хранят данные одного типа.
§2intЦелые числа
Тип int (от integer) хранит целые числа — без дробной части. Они бывают положительными, отрицательными и равными нулю: -10, 0, 5, 100. Ограничения на величину в Python нет: целое может быть сколь угодно большим, пока хватает памяти.
| Операция | Что делает | Пример при a = 10, b = 3 |
|---|---|---|
a + b | сложение | 13 |
a - b | вычитание | 7 |
a * b | умножение | 30 |
a / b | деление | 3.3333333333333335 — результат float |
a // b | целочисленное деление | 3 — сколько раз b помещается в a |
a % b | остаток от деления | 1 |
a ** b | возведение в степень | 1000 |
a = 10 b = 3 print(a + b) print(a * b) print(a // b) print(a % b)
13 30 3 1
Даже когда делится нацело: 10 / 2 возвращает 5.0, а не 5. Если нужен именно целый результат — берите //. Пара // и % постоянно работает вместе: она отвечает на вопросы «сколько целых поместилось» и «сколько осталось» — так считают минуты из секунд, страницы из записей, сдачу из суммы.
§3floatЧисла с дробной частью
Тип float хранит числа с дробной частью. Дробная часть отделяется точкой, а не запятой: 3.14, -0.5, 10.0, 0.001. Запись 10.0 — это уже float, хотя значение и целое.
Арифметика та же, что у целых. Если в выражении встречаются int и float, результат будет дробным — язык приводит оба значения к более общему типу.
a = 5.5 b = 2.0 print(a + b) # 7.5 print(a * b) # 11.0 print(a / b) # 2.75
float берут там, где целых не хватает: цена, вес, доля, результат измерения, любое деление. Но у этой точности есть цена, о которой лучше узнать сразу, а не на третьем месяце работы.
Компьютер хранит дробные числа в двоичной системе, и 0.1 в ней не записывается точно — так же, как 1/3 не записывается точно в десятичной. Поэтому print(0.1 + 0.2) выведет 0.30000000000000004. Это не ошибка Python, так устроены дробные числа во всех языках. При выводе округляйте: f"{value:.2f}", а для денег в серьёзных расчётах существует отдельный тип Decimal. И никогда не сравнивайте два float через ==.
§4strСтроки
Строка (string) — это последовательность символов: имя, сообщение, адрес, номер телефона. Записывается в кавычках, и кавычки могут быть трёх видов:
name = "Alice" # двойные message = 'Привет, мир!' # одинарные — то же самое text = """Строка, которая занимает несколько строк""" # тройные — с переносами
Двойные и одинарные кавычки равноправны; выбор нужен, когда кавычка встречается внутри самого текста: 'Он сказал "да"' пишется без ухищрений. Тройные кавычки удерживают переносы строк — их берут для длинного текста.
Что можно делать со строками
first = "Hello" second = "World" print(first + " " + second) # склеивание строк print("ha" * 3) # повторение print(len("Python")) # количество символов
Hello World hahaha 6
Обратите внимание на пробел в first + " " + second. Операция + склеивает строки ровно как есть, ничего не добавляя от себя, — без явного пробела получилось бы HelloWorld. И заметьте: знаки + и * для строк означают не арифметику, а склеивание и повторение. Одна и та же запись работает по-разному в зависимости от типа значений — как раз поэтому тип и важен.
§5boolЛогический тип и None
Помимо чисел и строк вам сразу встретятся ещё два типа, поэтому назовём их здесь коротко.
bool хранит одно из двух значений: True или False (с заглавной буквы, без кавычек). Такое значение получается при любом сравнении — 10 > 3 даёт True, — и именно на нём работают условия. Подробно разберём в главе о ветвлении.
None — отдельное значение со смыслом «значения пока нет». Его ставят, когда переменную нужно объявить, а данных для неё ещё не получено. Это не ноль и не пустая строка: ноль — это результат, а None — его отсутствие.
is_adult = 10 > 3 print(is_adult) # True print(type(is_adult)) # <class 'bool'> answer = None # ответа ещё нет
§6Строка с цифрами — не число
Это различие стоит отдельного параграфа, потому что на нём спотыкаются чаще всего. Значение "10" в кавычках — строка из двух символов. Значение 10 без кавычек — целое число. Выглядят похоже, ведут себя по-разному.
x = "10" y = 10 print(type(x)) # <class 'str'> print(type(y)) # <class 'int'> print(x * 2) # 1010 — строка повторилась дважды print(y * 2) # 20 — число умножилось на два
Вопрос не теоретический: функция input(), которой мы будем получать данные от пользователя, всегда возвращает строку — даже если человек ввёл цифры. Поэтому введённое значение почти всегда приходится преобразовывать перед вычислениями.
§7Преобразование типов
Перевести значение из одного типа в другой можно явно — функциями с именем типа.
| Функция | Что делает | Пример |
|---|---|---|
int(value) | приводит к целому числу | int("10") → 10 |
float(value) | приводит к дробному числу | float("3.5") → 3.5 |
str(value) | приводит к строке | str(10) → "10" |
x = "10" print(x + "10") # 1010 — склеили две строки print(int(x) + 10) # 20 — сложили два числа
У преобразования есть свои правила, и их лучше знать заранее:
int("3.5")— ошибкаValueError: функцияint()разбирает только запись целого числа. Через дробное — можно:int(float("3.5"))даст3;int(3.99)даёт3, аint(-3.7)даёт-3— дробная часть отбрасывается, а не округляется. Для округления по правилам естьround();int("десять")— ошибка: в строке должно быть число, а не его название.
§8Частые ошибки
| Что написано | Что произойдёт | Как правильно |
|---|---|---|
"10" + 10 | TypeError: can only concatenate str (not "int") to str | int("10") + 10 или "10" + str(10) — решаете вы, что нужно: сумма или склейка |
int("3.5") | ValueError: invalid literal for int() | float("3.5"), либо int(float("3.5")) |
x = 3,14 | не ошибка, но и не число: получится кортеж из двух значений | десятичный разделитель — точка: x = 3.14 |
print(10 / 2), ожидая 5 | выведет 5.0 — деление возвращает float | 10 // 2, если нужен целый результат |
print("Итого: " + total) | TypeError, если total — число | f-строка: print(f"Итого: {total}") |
x = "10" из input(), затем x * 2 | 1010 вместо 20 — сработало повторение строки | преобразовать сразу: x = int(input()) |
Сообщение can only concatenate str (not "int") to str переводится буквально: «к строке можно прибавить только строку, а не целое». Python в ошибках прямо называет типы, которые не сошлись, — этого почти всегда достаточно, чтобы понять, где значение оказалось не того рода. Читайте последнюю строку трассировки: там и тип, и номер строки в вашем файле.
§9Проверьте себя
Что выведет print(type(10.0))?
<class 'float'>. Наличие точки в записи делает значение дробным, даже если дробная часть нулевая. Целым числом было бы 10.
Чем отличается результат 7 / 2 от 7 // 2?
7 / 2 даёт 3.5 — обычное деление, результат всегда float. 7 // 2 даёт 3 — целочисленное деление: сколько целых двоек помещается в семёрке. Остаток от этого деления вернёт 7 % 2, то есть 1.
Что выведет программа: x = "5", затем print(x + x)?
55. Оба значения — строки, и + для строк означает склеивание. Чтобы получить 10, нужно преобразовать: print(int(x) + int(x)).
Пользователь ввёл возраст через input(). Почему age + 1 вызывает ошибку?
Потому что input() всегда возвращает строку, даже когда введены цифры. Прибавить целое к строке нельзя — будет TypeError. Преобразуйте значение сразу при вводе: age = int(input("Ваш возраст: ")).
Какого типа получится значение в выражении 2 + 3.0 и почему?
float, результат 5.0. Когда в выражении встречаются целое и дробное, целое приводится к дробному — иначе часть значения потерялась бы. Обратное приведение язык сам не делает никогда: терять данные без вашего ведома он не станет.
Задача для практики: программа из прошлой главы считает стоимость поездки. Что произойдёт, если distance получить через input() и ничего не менять?
Строка fuel_cost = (distance / fuel_efficiency) * fuel_price завершится с TypeError: делить строку на число нельзя. Правка в одном месте — distance = int(input("Расстояние, км: ")). Это и есть типичный порядок работы: получили данные строкой, привели к нужному типу, дальше считаем.
§10Шпаргалка
10 # int
3.14 # float
"текст" # str
True # bool
print(type(x))
# <class 'int'>
7 / 2 # 3.5 float
7 // 2 # 3 целое
7 % 2 # 1 остаток
"a" + "b" # ab
"ha" * 3 # hahaha
len("Python") # 6
int("10") # 10
float("3.5") # 3.5
str(10) # "10"
age = int(input())
price = float(input())
Итог главы
Тип данных отвечает на вопрос, что за значение лежит в переменной и что с ним разрешено делать. Целые числа — int, дробные — float, текст — str, результат сравнения — bool. Python определяет тип сам при присваивании, но не додумывает за вас смысл операции: сложить строку с числом он не станет, потому что не может знать, нужна вам сумма или склейка. Решаете это вы — явным преобразованием через int(), float() или str().