Consider the following piece of code:
def func1(a):
a[:] = [x**2 for x in a]
a = range(10)
print a #prints [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
func1(a[:5])
If you slice the list, you modify only a copy, so what you want to do doesn't work in the form you want.
But you could pass an optional slice object to func1 and if it's not None, use it to perform the slice assignment (else use [:])
I would do the following (used a lambda to avoid copy/paste of the formula and a generator expression to avoid creating a useless temporary list:
def func1(a,the_slice=None):
e = lambda y : (x**2 for x in y)
if the_slice:
a[the_slice] = e(a[the_slice])
else:
a[:] = e(a)
testing:
a = list(range(10))
func1(a)
print(a)
a = list(range(10))
func1(a,slice(5)) # stop at 5
print(a)
a = list(range(10))
func1(a,slice(5,len(a),2)) # start at 5 / stop at the end, stride/step 2
print(a)
result:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[0, 1, 4, 9, 16, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 25, 6, 49, 8, 81]
This will work:
a = range(10)
a[:5] = [c**2 for c in a[:5]]
a[:5] creates a new list. Hence, the changes that func1 applies to it are not mirrorred in a. You could add the slicing to the function:
def func1(a, start=None, stop=None, step=None):
start = start if start is not None else 0
stop = stop if stop is not None else len(a)
step = step if step is not None else 1
a[start:stop:step] = [x**2 for x in a[start:stop:step]]
func1(a, stop=5)