bytearray.pop()

The only bytearray mutator whose return value matters. It hands back an INT, not a one-byte bytes object.

Bytearray methodPython 3.0+Live demo
Common call
byte = buf.pop()
Returns
int — the removed byte value
Replaces
reading buf[-1] then deleting it
Watch out
IndexError on an empty buffer; there is no default argument
bytearray.pop([index])
→ int

Demo

Live evaluation
Try:
Inputs
sstrbuffer (as text)
Output
bytearray(bytes('abc', 'utf-8')).pop()
99

The demo shows what pop RETURNS — an integer, not bytes. Popping from "abc" gives 99, the ASCII code for c, and the buffer would be left holding just ab. The digits case is the usual trip-up: popping from "123" gives 51, the code for the character three, not the number three. An empty buffer raises IndexError, and unlike dict.pop there is no default argument to soften it.

Parameters

NameTypeRequiredDescription
indexintno (-1)Position to remove. Defaults to the last byte. Negative counts from the end. Out of range raises IndexError.

Return value

int — The removed byte as an integer from 0 to 255. Raises IndexError on an empty buffer.

Common patterns

Use a buffer as a byte stack
append and pop together give LIFO behaviour.
buf.append(value)
...
value = buf.pop()
Strip a trailing terminator
Removes and reports the byte in one step.
if buf and buf[-1] == 0x0a:
    buf.pop()
Drain the buffer
The truthiness test guards against the IndexError.
while buf:
    handle(buf.pop())

Examples

1. Pops the last
bytearray(b'abc').pop()
Returns
99
2. Buffer shrinks
b = bytearray(b'abc') b.pop() b
Returns
bytearray(b'ab')
3. By index
b = bytearray(b'abc') b.pop(0)
Returns
97
4. Digits are codes
bytearray(b'123').pop()
Returns
51 # not 3
5. Empty raises
bytearray().pop()
Returns
IndexError: pop from empty bytearray
6. Returns int
type(bytearray(b'a').pop())
Returns
<class 'int'>

Pitfalls

1. It returns an int, not bytes
Comparing the result against a bytes literal always fails, silently and without error, because an int is never equal to a bytes object.
Never equal
bytearray(b'abc').pop() == b'c'
False
Compare to an int
bytearray(b'abc').pop() == ord('c')
True
2. No default for an empty buffer
dict.pop accepts a fallback; this does not. Draining without a guard raises IndexError the moment the buffer empties.
Unguarded
while True:
    handle(buf.pop())
IndexError: pop from empty bytearray
Guard the loop
while buf:
    handle(buf.pop())
stops cleanly
3. Popping from the front is O(n)
pop(0) shifts every remaining byte left. Using a bytearray as a FIFO queue this way is quadratic — collections.deque is the right structure.
Shifts each time
while buf:
    handle(buf.pop(0))
quadratic
Use a deque
from collections import deque
q = deque(buf)
q.popleft()
O(1) per item
4. Digits pop as character codes
b'123' holds the characters, so popping gives 51 rather than 3. Treating byte values as the digits they look like is a classic parsing bug.
Character code
bytearray(b'123').pop()
51
Decode to parse
int(bytes(bytearray(b'123')))
123

When to use

Use it
  • Treating a buffer as a byte stack
  • Removing and inspecting a trailing byte in one step
  • Draining a buffer from the end
Reach for something else
  • FIFO order → collections.deque
  • You only want to look → index with buf[-1]
  • Removing by VALUE rather than position → remove

Notes

Complexity
O(1) from the end; O(n) from anywhere else because of the shift
Return
An int from 0 to 255; the buffer shrinks by one
CPython impl
Objects/bytearrayobject.c :: bytearray_pop
Memory
May shrink the internal buffer
Thread-safe
Not safe under concurrent mutation of the same buffer

FAQ

Because a bytearray is a sequence of integers — indexing gives an int, and so does popping. Only slicing produces a bytes object, which is the asymmetry behind most bytearray confusion.

b = bytearray(b'abc')
b[-1]      # 99
b[-1:]     # bytearray(b'c')

History

3.0
bytearray introduced as the mutable counterpart to bytes.