简体   繁体   中英

How to get the last byte item from a bytes list in Python?

I have a bytes list and want to get the last item, while preserving its bytes type. Using [-1] it gives out an int type, so this is not a direct solution.

Example code:

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

For an arbitrary index I know how to do it:

x = b'\x41\x42\x43'
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'>

Probably I can calculate the list length and then point an absolute length-1 number, rather than relative to list end.

However, is there a more elegant way to do this? (ie similar to the simple [-1]) I also cannot imagine how to adapt the [i:i+1] principle in reverse from list end.

There are a number of ways I think the one you're interested in is:

someBytes[-1:]

Edit: I just randomly decided to elaborate a bit on what is going on and why this works. A bytes object is an immutable arbitrary memory buffer so a single element of a bytes object is a byte, which is best represented by an int. This is why someBytes[-1] will be the last int in the buffer. It can be counterintuitive when you're using a bytes object like a string for whatever reason (pattern matching, handling ascii data and not bothering to convert to a string,) because a string in python (or a str to be pedantic,) represents the idea of textual data and isn't tied to any particular binary encoding (though it defaults to UTF-8). So the last element of "hello" is "o" which is a string since python has no single char type, just strings of length 1. So if you're treating a bytes object like a memory buffer you likely want an int but if you're treating it like a string you want a bytes object of length 1. So this line tells python to return a slice of the bytes object from the last element to the end of the bytes object which results in a slice length one containing only the last value in the bytes object and a slice of a bytes object is a bytes object.

You can trivially cast that int back to a bytes object:

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

...in the event that you can't easily get around fetching the values as ints, say because another function you don't have control of returns them that way.

If you have:

x = b'\x41\x42\x43'

Then you will get:

>>> x
b'ABC'

As you said, x[-1] will give you Ord() value.

>>> x[-1]
67

However, if you want to get the value of this, you can give:

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

If you do want to get the value 43, then you can give it as follows:

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

Example above

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

Same you can get with

x.strip()[-1:]

Output

b'C'

So,

bytes(b'\x41\x42\x43')

Give

b'ABC'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM