Как я могу преобразовать строку байтов в int в Python?
Скажи так: 'y\xcc\xa6\xbb'
Я придумал умный / глупый способ сделать это:
sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))
Я знаю, что должно быть что-то встроенное или в стандартной библиотеке, которая делает это проще ...
Это отличается от преобразования строки шестнадцатеричных цифр, для которой вы можете использовать int (xxx, 16), но вместо этого я хочу преобразовать строку фактических значений байтов.
ОБНОВИТЬ:
Мне нравится ответ Джеймса немного лучше, потому что он не требует импорта другого модуля, но метод Грега быстрее:
>>> from timeit import Timer
>>> Timer('struct.unpack("<L", "y\xcc\xa6\xbb")[0]', 'import struct').timeit()
0.36242198944091797
>>> Timer("int('y\xcc\xa6\xbb'.encode('hex'), 16)").timeit()
1.1432669162750244
Мой хакерский метод:
>>> Timer("sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))").timeit()
2.8819329738616943
ДОПОЛНИТЕЛЬНОЕ ОБНОВЛЕНИЕ:
Кто-то спросил в комментариях, в чем проблема с импортом другого модуля. Что ж, импорт модуля не обязательно дешев, посмотрите:
>>> Timer("""import struct\nstruct.unpack(">L", "y\xcc\xa6\xbb")[0]""").timeit()
0.98822188377380371
В том числе стоимость импорта модуля сводит на нет практически все преимущества этого метода. Я полагаю, что это будет включать только затраты на его импорт один раз для всего теста; посмотрите, что происходит, когда я заставляю его каждый раз перезагружаться
>>> Timer("""reload(struct)\nstruct.unpack(">L", "y\xcc\xa6\xbb")[0]""", 'import struct').timeit()
68.474128007888794
Излишне говорить, что если вы выполняете много операций этого метода для одного импорта, это становится пропорционально меньшей проблемой. Это также, вероятно, стоимость ввода-вывода, а не процессора, поэтому она может зависеть от производительности и характеристик нагрузки конкретной машины.
int.from_bytes
) не выполняется struct.unpack
на моем компьютере. Рядом с более читабельным ИМО.