Is there a special character on the end of Python strings? Like it is \0 in C or C++.
I want to count length of string in python without using the builtin len
function.
6 Answers
There is no end-of-string character in Python, at least not one that is exposed and it would be implementation dependent. String objects maintain their own length and it is not something that you need to be concerned with. There are several ways to get the string's length without using len()
.
str = 'man bites dog'
unistr = u'abcd\u3030\u3333'
# count characters in a loop
count = 0
for character in str:
count += 1
>>> count
13
# works for unicode strings too
count = 0
for character in unistr:
count += 1
>>> count
6
# use `string.count()`
>>> str.count('') - 1
13
>>> unistr.count(u'') - 1
6
# weird ways work too
>>> max(enumerate(str, 1))[0]
13
>>> max(enumerate(unistr, 1))[0]
6
>>> str.rindex(str[-1]) + 1
13
>>> unistr.rindex(unistr[-1]) + 1
6
# even weirder ways to do it
import re
pattern = re.compile(r'$')
match = pattern.search(str)
>>> match.endpos
13
match = pattern.search(unistr)
>>> match.endpos
6
I suspect that this is just the tip of the iceberg.

- 84,695
- 9
- 117
- 138
-
3Using regex to get the length of a string? That's the funniest thing I have seen today. – Shuklaswag Jan 06 '18 at 02:53
To answer the question that you asked: there isn't a terminating NULL or anything like that on the end of a Python string (that you can see), because there's no way for you to "fall off the end" of a string. Internally, the most popular Python implementation is written in C, so there probably is a NULL-terminated string somewhere under the hood. But that's completely opaque to you as a Python developer.
If you want to get the length without using a builtin function, you can do a number of different things. Here's an option that's different from the others posted here:
sum([1 for _ in "your string goes here"])
which is, in my opinion, a little more elegant.

- 10,306
- 5
- 30
- 69
-
3Python probably does NOT use null-termination internally, because strings can contain nulls: '\0' (echos '\x00') – Josiah Yoder Sep 14 '15 at 13:19
-
2@JosiahYoder Python strings store their length, so nothing stops you from using the length to tell when you see a null if it's part of the string or it's the null that terminates the string. In fact, CPython strings [*are* null-terminated internally](https://github.com/python/cpython/blob/b063b02eabf91bfd4edc0f3fde7ce8f0ebb392c4/Objects/unicodeobject.c#L1466). – Boris Verkhovskiy Dec 05 '21 at 09:20
count=0
for i in 'abcd':
count+=1
print 'lenth=',count
other way:
for i,j in enumerate('abcd'):
pass
print 'lenth=',i+1
enumerate
is a built in function that returns a tuple (index and value)
For example:
l= [7,8,9,10]
print 'index','value'
for i ,j in enumerate(l):
print i,j
outputs:
index value
0 7
1 8
2 9
3 10

- 778
- 1
- 11
- 25

- 8,524
- 2
- 34
- 46
-
-
thanks, still one question though, what is the end of string character , if there is any? – ayushgp Jun 25 '14 at 13:18
-
-
Several interesting things I found:
s_1 = '\x00'
print ("s_1 : " + s_1)
print ("length of s_1: " + str(len(s_1)))
s_2 = ''
print ("s_2 : " + s_2)
print ("length of s_2: " + str(len(s_2)))
if s_2 in s_1:
print ("s_2 in s_1")
else:
print ("s_2 not in s_1")
The output is:
s_1 :
length of s_1: 1
s_2 :
length of s_2: 0
s_2 in s_1
Here s_1 seems like a ' ' and s_2 seems like a '' or a NULL.

- 665
- 5
- 10
The short answer is no, they are length-prefixed, meaning they store their length before the text data begins. Your string can contain as many null characters as you want:
>>> len('\x00\x00\x00') # a string made up of 3 null characters
3
The long answer is that strictly speaking (on CPython) yes, under the hood, strings are also null terminated because CPython is written in C and in C strings are usually null terminated.
If we look at the source code of PyUnicode_New(size, maxchar)
which allocates space for a new string in Objects/unicodeobject.c
, we can see that we pass it size
, the number of characters we intend to store in the string, but then it allocates space for size + 1
characters:
obj = (PyObject *) PyObject_Malloc(struct_size + (size + 1) * char_size);
and then depending on char_size
we set that extra character at the end to a 0 of the appropriate size. char_size
is how many bytes each character should take up and can be either 1, 2 or 4. It's set from the second argument we pass in, maxchar
and has to do with how Python strings work: if your text contains only ASCII characters, each character will only take up 1 byte, if your string contains at least one emoji, all characters will use 4 bytes each.
If char_size
is 1
:
((char*)data)[size] = 0;
and if char_size
is 2 or 4:
if (kind == PyUnicode_2BYTE_KIND)
((Py_UCS2*)data)[size] = 0;
else /* kind == PyUnicode_4BYTE_KIND */
((Py_UCS4*)data)[size] = 0;
So CPython strings actually have 1, 2 or even 4 terminating nulls.
This terminating null is not exposed to you when you're coding in Python though. You can tell that it's there if you look at how much memory is used by an empty string:
>>> sys.getsizeof('')
49
That's 48 bytes for the struct (the metadata of the Python object) + 1 byte for the terminating null.

- 14,854
- 11
- 100
- 103
Came here for the answer, Now posting what I found:
def rec_len(s, k = 0):
try:
c = s[k]
return 1 + rec_len(s, k + 1)
except:
return 0
print(rec_len("DoIt"))

- 9
- 1