Как я могу преобразовать строку байтов в 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
Излишне говорить, что если вы выполняете много операций этого метода для одного импорта, то это становится пропорционально меньшей проблемой. Вероятно, это также стоимость ввода-вывода, а не процессора, поэтому она может зависеть от производительности и характеристик нагрузки конкретной машины.