Як я можу перетворити рядок байтів у 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
на моєму комп’ютері. Поруч з тим, що є більш читабельним imo.