Преобразование шестнадцатеричного символа в int в Python - PullRequest
2 голосов
/ 03 мая 2011

Я использую графическую библиотеку Pyglet для рисования и хочу вывести полученное изображение в виде списка Python (чтобы я мог преобразовать его в массив NumPy ).

Пиглет дает мне строку шестнадцатеричных символов, например: '\ xff' (указывающая значение 255 на один пиксель).Как я могу преобразовать такую ​​строку в int?

Я пробовал int ('\ xff', 16), но это не работает.Обратите внимание, что согласно документации , '\ xnn' экранируется и кодируется как шестнадцатеричный символ, но он не говорит мне, как преобразовать это в целое число.

Ответы [ 4 ]

10 голосов
/ 03 мая 2011

Чтобы получить массив NumPy прямо из строки Python, вы можете использовать

s = "\xff\x03"
a = numpy.frombuffer(s, numpy.uint8)

Чтобы получить список, вы можете использовать

a =  map(ord, s)

Альтернатива списку в Python 2.6или выше использовать bytesarray(s).

3 голосов
/ 03 мая 2011

Попробуйте что-то вроде этого:

a = '\xff'
print int(a.encode('hex'), 16)
255

Редактировать: извините, в предыдущей версии была ошибка - декодировать вместо кодирования. Это работает.

Редактировать 2: Я действительно неправильно понял вопрос, как отметили комментаторы. Это может быть уже очевидно, но в случае, если кто-то сочтет это полезным, обычное решение для списка Python будет:

>>> a = '\xff\xfe'
>>> [str(ord(char)) for char in a]
['255', '254']
>>> ' '.join([str(ord(char)) for char in a])
'255 254'
1 голос
/ 29 марта 2016

Вот обобщенный подход, который обрабатывает шестнадцатеричную строку с подстрокой переменной длины, например:

s = '5b1\n5\n3ad44'

Следующий код преобразует строку с 3 миллионами шестнадцатеричных подстрок переменной длины в массив целых чисел за 2 секунды (на MacBook) через векторизацию:

import numpy as np, pandas as pd, cStringIO

s = ('5b1\n5\n3ad44\n' * 1000000)[:-1]    # 3m item hex string (variable element length)

# change hex to 2 digit decimal
for i in range(0,9): s = s.replace(str(i),'0' + str(i))  
for i in [['a','10'],['b','11'],['c','12'],['d','13'],['e','14'],['f','15']]:
    s = s.replace(i[0],i[1])

# read string into numpy
n = np.array(pd.read_csv(cStringIO.StringIO(s), header=None)[[0]]).astype('int64')    

# fix base
n = (n % 100) + 16 * ((n % 10000)/100) + 256 * ((n % 1000000)/10000) + 4096 * ((n % 100000000)/1000000) + 65536 * ((n % 10000000000)/100000000)

n[0:3]    # confirm correct transformation to [1457, 5, 240964]
0 голосов
/ 03 мая 2011

Да, \xff - это печатное представление шестнадцатеричного значения в байте. Но int() работает не с шестнадцатеричным представлением байтов, а со строковым представлением чисел. Число в мире base-16 - это «13» или «ab» или «ff». Следовательно (но все же забавно), int('ff',16) работает нормально. Если вы хотите пойти по этому пути, вам нужно избавиться от '\ x': -).

...