Как преобразовать строку байтов в int в python?
Скажите так: 'y\xcc\xa6\xbb'
Я придумал умный/глупый способ сделать это:
sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))
Я знаю, что должно быть что-то встроенное или в стандартную библиотеку, которая делает это проще...
Это отличается от преобразование строки шестнадцатеричных цифр, для которой вы можете использовать int (xxx, 16), но вместо этого я хочу преобразовать строку фактического байта значения.
UPDATE:
Я вроде как ответ Джеймса немного лучше, потому что он не требует импорта другого модуля, но метод Грега выполняется быстрее:
>>> 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
Излишне говорить, что если вы делаете много исполнений этого метода за один импорт, это становится менее пропорциональным. Это также, вероятно, стоимость ввода-вывода, а не процессора, поэтому он может зависеть от характеристик емкости и нагрузки конкретной машины.