Значение символа в Python: функции ord и chr
Основное решение: функции ord() и chr()
Функция ord(c) принимает один символ (строку длины 1) и возвращает его числовой код Unicode. Функция chr(code) выполняет обратное преобразование: принимает целое число (код) и возвращает символ.
symbol = 'A'
code = ord(symbol) # 65
print(code) # 65
print(chr(code)) # APython значение символа (значение символа в python)
Для символов, не входящих в ASCII (например, кириллица, иероглифы, эмодзи), ord возвращает код Unicode, который может быть больше 255.
Цель: получение числового представления символа необходимо для сортировки, шифрования, проверки диапазона символов, работы с кодировками.
Как отобразить код символа в шестнадцатеричном формате?
hex_code = hex(ord('A')) # '0x41'
print(hex_code)
Шестнадцатеричное представление часто используется в отладке, при работе с байтами, в таблицах символов.
Как получить символ по коду, если код задан в десятичной или шестнадцатеричной системе?
print(chr(1040)) # 'А' (кириллица)
print(chr(0x0410)) # 'А' (если передать int)
Функция chr() работает с любым допустимым кодом Unicode от 0 до 0x10FFFF.
Как обработать строку, содержащую суррогатные пары (например, эмодзи)?
emoji = '?'
print(len(emoji)) # 1 (один символ в логическом смысле)
print(ord(emoji)) # 128512
# Для работы с суррогатами вручную:
high_surrogate = '\ud83d' # суррогатная пара
low_surrogate = '\ude00'
print(ord(high_surrogate), ord(low_surrogate)) # 55357, 56832
code_point = 0x10000 + (ord(high_surrogate) - 0xD800) * 0x400 + (ord(low_surrogate) - 0xDC00)
print(code_point) # 128512
Типичная ошибка: путаница между логическим символом и физическим представлением. В современных версиях Python (3.3+) строки используют Unicode с переменной длиной кодовых точек, но для символов вне BMP (Basic Multilingual Plane) они представляются как два суррогата только при кодировании в UTF-16. В самом Python каждая кодовая точка - это отдельный символ, поэтому ord(?) работает напрямую. Ошибка возникает, если попытаться передать в ord строку из двух символов (суррогатов), которая не является валидной строкой в Python.
Как получить байтовое представление символа в конкретной кодировке?
char = 'è'
print(char.encode('utf-8')) # b'\xc3\xa8'
print(char.encode('utf-16')) # b'\xff\xfe\xe8\x00'
Метод .encode() возвращает байтовую строку. Полезно при записи в файл или передаче по сети, где требуется указать кодировку.
Как сравнить символы по их числовому значению?
char1 = 'b'
char2 = 'a'
print(ord(char1) > ord(char2)) # True
print('b' > 'a') # Python сам сравнивает по Unicode
Явное сравнение через ord даёт контроль над тем, как именно производится сравнение (например, можно игнорировать регистр, предварительно преобразовав коды).
Общие ошибки при работе с ord и chr:
- Передача в ord строки длиннее одного символа: TypeError: ord() expected a character, but string of length N found. Перед вызовом нужно убедиться, что длина равна 1.
- Передача в chr числа вне диапазона 0..0x10FFFF: ValueError: chr() arg not in range(0x110000). Необходимо проверять значение.
- Путаница между ASCII и Unicode: ord('A') возвращает 65, но ord('А') (кириллица) возвращает 1040.
- Неправильная обработка суррогатных пар при ручном разборе строк в старых версиях Python.
Расширенные примеры работы с числовыми значениями символов
Пример 1. Получение списка кодов всех символов строки
text = "Привет, мир!"
codes = [ord(c) for c in text]
print(codes)
[1055, 1088, 1080, 1074, 1077, 1090, 44, 32, 1084, 1080, 1088, 33]
Генератор списка последовательно вызывает ord для каждого символа. Результат - список десятичных кодов Unicode.
Пример 2. Сортировка списка строк по первой букве с использованием ord
words = ['яблоко', 'арбуз', 'вишня']
sorted_words = sorted(words, key=lambda x: ord(x[0]))
print(sorted_words)
['арбуз', 'вишня', 'яблоко']
Параметр key принимает функцию, которая возвращает числовой код первого символа. Так можно менять порядок сортировки.
Пример 3. Проверка, является ли символ буквой, цифрой или знаком препинания через сравнение кодов
char = '5'
code = ord(char)
if ord('0') <= code <= ord('9'):
print(f"'{char}' - это цифра")
elif ord('A') <= code <= ord('Z') or ord('a') <= code <= ord('z'):
print(f"'{char}' - это латинская буква")
else:
print(f"'{char}' - это другой символ")
'5' - это цифра
Используя диапазоны кодов, можно классифицировать символы без импорта дополнительных модулей.
Пример 4. Создание строки из кодов с проверкой на валидность
codes = [65, 66, 67, 128512]
valid_chars = []
for code in codes:
if 0 <= code <= 0x10FFFF:
char = chr(code)
if char.isprintable():
valid_chars.append(char)
print(''.join(valid_chars))
ABC?
Проверка isprintable() отсеивает управляющие символы и непечатные коды.
Пример 5. Обработка эмодзи: получение фактического Unicode кода из суррогатной пары
# Строка, содержащая эмодзи, может быть представлена как два суррогата в UTF-16
high = '\ud83d'
low = '\ude00'
# Вычисление кода по формуле
cp = 0x10000 + (ord(high) - 0xD800) * 0x400 + (ord(low) - 0xDC00)
print(hex(cp), cp) # 0x1f600 128512
0x1f600 128512
Этот способ полезен при анализе данных, закодированных в UTF-16, например, при чтении из файлов или сетевых протоколов.
Пример 6. Использование int.from_bytes для получения кода из байтов UTF-8
byte_seq = b'\xe2\x82\xac' # UTF-8 представление символа '€'
code = int.from_bytes(byte_seq, byteorder='big')
# Однако для правильной интерпретации нужно декодировать:
import struct
code_via_decode = byte_seq.decode('utf-8')
print(ord(code_via_decode)) # 8364
# Более прямой метод с использованием struct:
if len(byte_seq) == 3:
# Для UTF-8 из 3 байтов можно вручную извлечь код
code_manual = ((byte_seq[0] & 0x0F) << 12) | ((byte_seq[1] & 0x3F) << 6) | (byte_seq[2] & 0x3F)
print(code_manual)
8364 8364
Прямое преобразование байтов в число без декодирования требует знания структуры UTF-8, но иногда необходимо для низкоуровневой работы.
Пример 7. Шифр Цезаря с помощью ord и chr
text = "Hello, World!"
shift = 3
encrypted = ''
for char in text:
if char.isalpha():
base = ord('A') if char.isupper() else ord('a')
shifted = (ord(char) - base + shift) % 26 + base
encrypted += chr(shifted)
else:
encrypted += char
print(encrypted)
Khoor, Zruog!
Сдвиг выполняется через арифметику кодов, с сохранением регистра и оставлением неалфавитных символов без изменений.