Как получить последний байтовый элемент из списка байтов в Python?

#python

#python

Вопрос:

У меня есть список байтов, и я хочу получить последний элемент, сохранив при этом его тип байтов. Используя [-1], он выдает тип int, так что это не прямое решение.

Пример кода:

 x = b'x41x42x43'
y = x[-1]
print (y, type(y))
# outputs:
67 <class 'int'>
 

Для произвольного индекса я знаю, как это сделать:

 x = b'x41x42x43'
i = 2 # assume here a valid index in reference to list length
y = x[i:i 1]
print (y, type(y))
# outputs:
b'C' <class 'bytes'>
 

Вероятно, я могу вычислить длину списка, а затем указать число абсолютной длины-1, а не относительно конца списка.

Однако есть ли более элегантный способ сделать это? (т.е. аналогично простому [-1]) Я также не могу себе представить, как адаптировать принцип [i: i 1] в обратном порядке от конца списка.

Ответ №1:

Есть несколько способов, которые, я думаю, вас интересуют:

 someBytes[-1:]
 

Редактировать: я просто случайно решил немного рассказать о том, что происходит и почему это работает. Объект bytes является неизменяемым произвольным буфером памяти, поэтому единственным элементом объекта bytes является byte , который лучше всего представлен int . Вот почему someBytes[-1] будет последним int в буфере. Это может противоречить здравому смыслу, когда вы используете объект bytes как строку по какой-либо причине (сопоставление с образцом, обработка данных ascii и не утруждение преобразованием в строку), потому что строка в python (или str, чтобы быть педантичным) представляет идею текстовых данных и не привязана ни к какомуопределенная двоичная кодировка (хотя по умолчанию используется UTF-8). Итак, последним элементом «hello» является «o», который является строкой, поскольку в python нет ни одного типа символа, только строки длиной 1. Итак, если вы обрабатываете объект bytes как буфер памяти, вам, вероятно, нужен int, но если вы обрабатываете его как строку, вам нужен объект bytes длиной 1. Итак, эта строка сообщает python вернуть фрагмент объекта bytes от последнего элемента до конца объекта bytes, что приводит к фрагменту длиной, содержащему только последнее значение в объекте bytes, а фрагмент объекта bytes является объектом bytes.

Ответ №2:

Вы можете тривиально преобразовать этот int обратно в bytes объект:

 >>> z = bytes([y])
>>> z == b'C'
True
 

… в случае, если вы не можете легко обойти выборку значений в виде целых чисел, скажем, потому, что другая функция, которую вы не контролируете, возвращает их таким образом.

Ответ №3:

Если у вас есть:

 x = b'x41x42x43'
 

Тогда вы получите:

 >>> x
b'ABC'
 

Как вы сказали, x[-1] даст вам значение Ord() .

 >>> x[-1]
67
 

Однако, если вы хотите получить значение этого, вы можете указать:

 >>> x.decode()[-1]
'C'
 

Если вы хотите получить значение 43, вы можете указать его следующим образом:

 >>> "{0:x}".format(x[-1])
'43'
 

Комментарии:

1. Для чистого ASCII это было бы хорошо, но я предпочитаю избегать обработки кодирования / декодирования (если это возможно), когда отдельные байты могут быть случайными в диапазоне 0x00-0xff (даже если возможна явная кодировка ‘Latin-1’).

Ответ №4:

Пример выше

 >>> z = bytes([y])
>>> z == b'C'
True
 

То же самое вы можете получить с

 x.strip()[-1:]
 

Вывод

 b'C'
 

Итак,

 bytes(b'x41x42x43')
 

Дайте

 b'ABC'