secarica
secarica

Reputation: 619

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 ? (i.e. similar to the simple [-1]) I also cannot imagine how to adapt the [i:i+1] principle in reverse from list end.

Upvotes: 5

Views: 11505

Answers (4)

David Oldford
David Oldford

Reputation: 1175

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.

Upvotes: 6

Joe Ferndz
Joe Ferndz

Reputation: 8508

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'

Upvotes: 0

circassia_ai
circassia_ai

Reputation: 422

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'

Upvotes: 0

Kirk Strauser
Kirk Strauser

Reputation: 30933

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.

Upvotes: 1

Related Questions