This operation is called slicing and it avoids function calls. Slicing can be done with any sequence.
# exploring Python's slicing operator
# can be used with any indexed sequence like strings, lists, ...
# syntax --> seq[begin : end : step]
# step is optional
# defaults are index begin=0, index end=len(seq)-1, step=1
# -begin or -end --> count from the end backwards
# step = -1 reverses sequence
# if you feel lost, put in the defaults in your mind
# use a list as a test sequence
a = [0, 1, 2, 3, 4, 5, 6, 7, 8]
print( a[3:6] ) # [3,4,5]
# if either index is omitted, beginning or end of sequence is assumed
print( a[:3] ) # [0,1,2]
print( a[5:] ) # [5,6,7,8]
# negative index is taken from the end of the sequence
print( a[2:-2] ) # [2,3,4,5,6]
print( a[-4:] ) # [5,6,7,8]
# extract every second element
print( a[::2] ) # [0, 2, 4, 6, 8]
# step=-1 will reverse the sequence
print( a[::-1] ) # [8, 7, 6, 5, 4, 3, 2, 1, 0]
# no indices just makes a copy (which is sometimes useful)
b = a[:]
print( b ) # [0, 1, 2, 3, 4, 5, 6, 7, 8]
# slice in a few elements starting at index 3
b[3:] = [9, 9, 9, 9] + b[3:]
print( a ) # [0, 1, 2, 3, 4, 5, 6, 7, 8]
print( b ) # [0, 1, 2, 9, 9, 9, 9, 3, 4, 5, 6, 7, 8]