Jak mogę przekonwertować ciąg bajtów na int w Pythonie?
Powiedz tak: 'y\xcc\xa6\xbb'
Wymyśliłem sprytny / głupi sposób na zrobienie tego:
sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))
Wiem, że musi być coś wbudowanego lub w standardowej bibliotece, które robi to prościej ...
Różni się to od konwersji ciągu cyfr szesnastkowych, dla których można użyć int (xxx, 16), ale zamiast tego chcę przekonwertować ciąg rzeczywistych wartości bajtów.
AKTUALIZACJA:
Odpowiedź Jamesa podoba mi się trochę lepiej, ponieważ nie wymaga importowania innego modułu, ale metoda Grega jest szybsza:
>>> 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
Moja zhackowana metoda:
>>> Timer("sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))").timeit()
2.8819329738616943
DALSZA AKTUALIZACJA:
Ktoś w komentarzach zapytał, jaki jest problem z importem innego modułu. Cóż, importowanie modułu niekoniecznie jest tanie, spójrz:
>>> Timer("""import struct\nstruct.unpack(">L", "y\xcc\xa6\xbb")[0]""").timeit()
0.98822188377380371
Uwzględnienie kosztu importu modułu neguje prawie wszystkie zalety tej metody. Uważam, że będzie to obejmować koszt importu tylko raz na cały przebieg benchmarku; zobacz, co się dzieje, gdy za każdym razem zmuszam go do ponownego ładowania:
>>> Timer("""reload(struct)\nstruct.unpack(">L", "y\xcc\xa6\xbb")[0]""", 'import struct').timeit()
68.474128007888794
Nie trzeba dodawać, że jeśli wykonujesz wiele wykonań tej metody na jeden import, to staje się to proporcjonalnie mniejszym problemem. Prawdopodobnie jest to również koszt wejścia / wyjścia, a nie procesora, więc może to zależeć od pojemności i charakterystyki obciążenia konkretnej maszyny.
int.from_bytes) jest lepsza niż struct.unpackna moim komputerze. Oprócz większej czytelności imo.