Python's str()
does slicing s[1:]
in O(n)
time, because str() is immutable and any slicing operations create whole new string and copies all slice data, so for string of length N this operations is O(N).
To do any slicing in O(1)
time you need to use special implementations, like Numpy has for its arrays. Numpy arrays keep pointer to allocated array plus three extra fields begin
, end
, stride
.
Before slicing Numpy's array having N elements will start with begin=0, end=N. After slicing e.g. a[1:], unlike str() Numpy array doesn't copy any memory but just changes begin/end/stride. Memory pointer and size remain the same. Thus after a[1:] we will have begin=1, end=N. After one more a[1:] we will have begin=2, end=N.
For strings you can convert them one time at program beginning to Numpy arrays of uint32 elements (because Unicode code point is 32-bit at current time). Then do all the operations inside your program only in Numpy arrays. Numpy also has many string operations implemented for its arrays.
You can do slicing and many other operations very fast, much faster than working with Python's str(). And all slicing operations are done in O(1)
time. After you're done with Numpy operations you convert back to Python's str().
Next follows example of code. It first converts Python str() to numpy array. Then does any operations including slicing (slicing is done in O(1) time on numpy arrays). And when we're finished numpy array is converted back to Python's str().
Try it online!
import numpy as np
s = 'abcde'
# Convert string to Numpy array
a = np.frombuffer(s.encode('utf-32-le'), dtype = np.uint32)
# Do any slicing operations in O(1) time
a = a[1:]
a = a[1:]
# Convert Numpy array to string
s = a.tobytes().decode('utf-32-le')
print(s)
Output:
cde