bytes.count()

The bytes twin of str.count. Same counting rules — including the non-overlapping one — but it counts BYTES, and it rejects a str argument outright.

Bytes methodPython 3.0+Live demo
Common call
data.count(b'x')
Returns
int — non-overlapping matches
Replaces
a manual scan over the buffer
Watch out
the argument must be bytes; data.count('x') is a TypeError
bytes.count(sub[, start[, end]])
→ int

Demo

Live evaluation
Try:
Inputs
sstrdata (encoded as utf-8)
substrsequence to count
Output
bytes('abcabc', 'utf-8').count(bytes('a', 'utf-8'))
2

Counting works exactly as it does on strings, with two byte-level twists. Matches do not overlap: "aaa" contains "aa" only once, because the scan resumes after each match rather than one position later. And the empty sequence is found at every gap, giving length plus one. The non-ascii case counts a two-byte UTF-8 sequence as a single match, because both the data and the argument were encoded the same way.

Parameters

NameTypeRequiredDescription
subbytes | intyesByte sequence to count. A plain int from 0 to 255 also works, counting that single byte value.
startintno (0)Byte offset to begin at.
endintno (len)Byte offset to stop at, exclusive.

Return value

int — Number of non-overlapping occurrences of sub. Returns 0 when absent, never raises.

Common patterns

Count records in a buffer
Delimiter counting without splitting, which avoids allocating the parts.
record_count = payload.count(b'\n')
Sanity-check a binary format
Cheap validation before a real parse.
if data.count(b'\x00') > MAX_NULLS:
    raise ValueError('looks corrupt')
Count a single byte value
An int argument counts that byte without building a one-byte object.
zeros = data.count(0)

Examples

1. Twice
b'abcabc'.count(b'a')
Returns
2
2. Absent
b'abc'.count(b'z')
Returns
0
3. No overlaps
b'aaa'.count(b'aa')
Returns
1
4. Empty sub
b'abc'.count(b'')
Returns
4
5. Int argument
b'a\x00b'.count(0)
Returns
1
6. str rejected
b'abc'.count('a')
Returns
TypeError: argument should be integer or bytes-like object, not 'str'

Pitfalls

1. A str argument is a TypeError
The single most common mistake with every bytes method. Python will not encode the argument for you, because it cannot know which codec you meant.
str rejected
b'abc'.count('a')
TypeError: argument should be integer or bytes-like object, not 'str'
Use a bytes literal
b'abc'.count(b'a')
1
2. Matches do not overlap
After a match the scan resumes past it, so "aaa" contains "aa" once, not twice. Counting overlapping patterns needs a manual loop or a regex with a lookahead.
One, not two
b'aaa'.count(b'aa')
1
Count overlaps
sum(1 for i in range(len(d)-1) if d[i:i+2] == b'aa')
2
3. Counts bytes, not characters
A non-ASCII character is several UTF-8 bytes. Counting inside encoded text gives byte-level answers that will not match what you see on screen.
Byte length differs
len('héllo'.encode())
6, not 5
Decode first
'héllo'.encode().decode().count('l')
character-level

When to use

Use it
  • Counting delimiters or markers in a binary buffer
  • Cheap validation before parsing a format
  • Counting a single byte value with an int argument
Reach for something else
  • The data is text → decode first and count characters
  • Overlapping matches → a manual loop or a lookahead regex
  • You want the POSITION → find or index

Notes

Complexity
O(n * m) worst case; the same search machinery as str.count
Return
A non-negative int; 0 when absent
CPython impl
Objects/bytesobject.c :: bytes_count
Memory
No allocation — scans in place
Thread-safe
Yes — bytes are immutable

FAQ

Because Python refuses to guess an encoding. Counting b'é' means counting two specific bytes, and which two depends on the codec — so you must encode the argument yourself and make that choice explicit.

data.count('é'.encode('utf-8'))

History

3.0
bytes.count arrived with the bytes type in the text/binary split.
3.3
An int argument accepted, counting a single byte value.