Целые числа (int) в языке Python
Объект int в Python
int в Python - это неизменяемый тип данных для представления целых чисел произвольной точности. Он поддерживает все стандартные арифметические операции, сравнения, битовые операции, а также методы преобразования и анализа. В отличие от некоторых языков, целые числа в Python не ограничены фиксированным количеством бит (кроме выделяемой памяти). Объекты int создаются при записи целого числа в коде (например, 42) или при вызове конструктора int(). Они используются повсеместно: от счётчиков до индексов и флаговых масок.
Базовое создание:
a = 5
b = int(3.14) # преобразование из float
c = int("1010", 2) # 10 в десятичнойPython callable object (вызываемый объект в python)
print(a, b, c) # 5 3 10
Int object python (объект int в python)
Как преобразовать строку с числом в объект int?
Самый простой способ - использовать конструктор int() со строкой в качестве аргумента. Он корректно обрабатывает ведущие пробелы и знаки.
s = " -42 "
num = int(s)
print(num)
встроенные типы python (встроенные типы python)
-42
Цель: парсинг пользовательского ввода или данных из текстовых файлов.
Типичная ошибка: если строка содержит нечисловые символы (кроме знака и пробелов), возникает ValueError. Решение - предварительная проверка или перехват исключения.
try:
val = int("123a")
except ValueError as e:
print("Ошибка:", e)
Ошибка: invalid literal for int() with base 10: '123a'
Как создать int из строки с нестандартным основанием?
Второй аргумент int() задаёт основание системы счисления (от 2 до 36). Это позволяет разбирать двоичные, восьмеричные, шестнадцатеричные и другие записи.
bin_str = "1101"
oct_str = "17"
hex_str = "FF"
print(int(bin_str, 2)) # 13
print(int(oct_str, 8)) # 15
print(int(hex_str, 16)) # 255
13 15 255
Случаи использования: работа с цветами (HEX), декодирование сетевых адресов, бинарные протоколы.
Как получить целую часть от деления без округления?
Оператор // выполняет деление с округлением вниз (пол). Для положительных чисел это обычное целочисленное деление, для отрицательных - результат меньше или равен точному частному.
print(7 // 2) # 3
print(-7 // 2) # -4 (а не -3)
3 -4
Проблема: новички ожидают усечение к нулю при отрицательных числах. Для усечения к нулю используется int() от результата обычного деления или math.trunc().
import math
print(int(-7/2)) # -3
print(math.trunc(-7/2)) # -3
Как выполнить побитовые операции с целыми числами?
Python предоставляет полный набор побитовых операторов: & (И), | (ИЛИ), ^ (исключающее ИЛИ), ~ (НЕ), << (сдвиг влево), >> (сдвиг вправо). Они работают с бесконечной битовой длиной (отрицательные числа хранятся в дополнительном коде).
a = 0b1100 # 12
b = 0b1010 # 10
print(a & b) # 1000 -> 8
print(a | b) # 1110 -> 14
print(a ^ b) # 0110 -> 6
print(~a) # -13 (инвертирование всех битов)
print(a << 1) # 11000 -> 24
print(a >> 1) # 110 -> 6
8 14 6 -13 24 6
Применения: флаговые маски, кодирование/декодирование, работа с аппаратными регистрами.
Как определить количество бит, необходимых для представления числа?
Метод bit_length() возвращает минимальное количество бит без учёта знака. Для нуля возвращает 0.
print((10).bit_length()) # 4 (1010)
print((0).bit_length()) # 0
print((-10).bit_length()) # 10? Нет, для отрицательных считается по модулю: 4
4 0 4
Когда пригодится: оценка размера данных, выделение памяти, оптимизация битовых структур.
Как преобразовать int в последовательность байт?
Метод to_bytes(length, byteorder) (Python 3.2+) возвращает байтовый объект фиксированной длины. Порядок байт - 'big' или 'little'. Для работы с интеграцией с C, сетевыми протоколами, файловыми форматами.
x = 0x1234
print(x.to_bytes(2, 'big')) # b'\x12\x34'
print(x.to_bytes(2, 'little'))# b'\x34\x12'
b'\x12\x34' b'\x34\x12'
Ошибка: если длина недостаточна, возникает OverflowError. Решение - заранее вычислить bit_length и поделить на 8.
Как преобразовать последовательность байт обратно в int?
Классный метод int.from_bytes(bytes, byteorder) восстанавливает целое число из байтов.
b = b'\x12\x34'
print(int.from_bytes(b, 'big')) # 4660
print(int.from_bytes(b, 'little')) # 13330
4660 13330
Использование: чтение бинарных данных из сокетов, файлов, структур C (struct.unpack тоже может, но from_bytes проще).
Продвинутые примеры работы с int
1. Подсчёт установленных бит (bit_count)
Метод bit_count() (Python 3.8+) возвращает количество единичных бит в двоичном представлении числа. Это эффективный способ проверки чётности числа единиц, анализа битовых масок.
x = 0b101101
print(x.bit_count()) # 4 (биты: 1+0+1+1+0+1)
4
Сравнение с циклом:
def popcount_loop(n):
count = 0
while n:
count += n & 1
n >>= 1
return count
print(popcount_loop(0b101101)) # 4
Пояснение: bit_count реализован на C и работает быстрее на больших числах. Подходит для криптографии, контроля ошибок (Hamming weight).
2. int как вызываемый объект для iter
Объект int может выступать в качестве функции, возвращающей всегда 0. Это нестандартное использование, возможное благодаря тому, что int() без аргумента возвращает 0. В сочетании с iter(callable, sentinel) можно создать бесконечную последовательность нулей до достижения стоп-значения.
import itertools
# Бесконечный генератор нулей
zero_gen = iter(int, 1) # int() будет вызываться, пока не вернёт 1 (никогда)
print(list(itertools.islice(zero_gen, 5))) # [0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
Цель: создание однородного итератора без лямбда-функции, хотя обычно используют itertools.repeat(0).
3. Преобразование между системами счисления с помощью format
Метод format() и f-строки позволяют легко получить строковое представление в разных системах счисления с префиксами.
x = 255
print(bin(x)) # '0b11111111'
print(oct(x)) # '0o377'
print(hex(x)) # '0xff'
# Без префиксов
print(f"{x:b}") # '11111111'
print(f"{x:#x}") # '0xff' (с префиксом)
0b11111111 0o377 0xff 11111111 0xff
Подводный камень: bin() всегда выдаёт префикс '0b', его можно удалить срезом [2:]. Для больших отрицательных чисел работает дополнительный код с бесконечными единицами - bin(-1) вернёт '-0b1'.
4. int в качестве хеша и ключа словаря
Хеш целого числа равен самому числу (для чисел, укладывающихся в машинное слово, иначе - по модулю). Это делает int идеальным ключом для словарей - быстрое сравнение и вычисление хеша.
d = {10: 'десять', -3: 'минус три'}
print(hash(10)) # 10
print(hash(0x10000000000000000)) # возможно, другое значение
10 4294967296
Интересный факт: hash(0) == hash(False) и hash(1) == hash(True), поэтому ключи 0 и False считаются одинаковыми.
d = {0: 'ноль', False: 'ложь'}
print(d[0]) # 'ложь' (последняя запись перезаписала)
ложь
5. int и memoryview
Целые числа могут быть напрямую интерпретированы как байтовые буферы через to_bytes, но не через memoryview - он не поддерживает int. Однако можно создать массив из одного int и получить memoryview на него.
import array
arr = array.array('i', [0x12345678]) # 4-байтовое знаковое целое
mv = memoryview(arr)
print(mv.cast('B').tolist()) # список байт (маленький endian на x86)
[120, 86, 52, 18]
Пояснение: такой подход используется при работе с бинарными форматами изображений или сокетами, где требуется изменять байты без копирования.