Given the following list:
x =[None, None, 1, 2, None, None, 3, 4, None, 5, None, None]
The question asks us to replace None values with the previous value.
When I run both these solutions in Google Colab, they result in the identical answer:
x =[None, None, 1, 2, None, None, 3, 4, None, 5, None, None]
def replace(x):
for i,v in enumerate(x):
if x[i] is None:
x[i]=x[i-1]
return x
y =[None, None, 1, 2, None, None, 3, 4, None, 5, None, None]
def replace(y):
for i,v in enumerate(y[:-1],1):
if y[i] is None:
y[i]=y[i-1]
return y
Both return the following:
[None, None, 1, 2, 2, 2, 3, 4, 4, 5, 5, 5]
I'm trying to understand why these solutions are equivalent. Additionally, given the equivalence, what is the rationale for the y[:-1] in the enumerate statement?
Thank you.
CodePudding user response:
They are not completely equivalent. The first solution will use the last item in the list to replace the None value at index 0. The second solution does not replace the item at index zero (given that it has no predecessor). So, depending on the wording of the problem statement, one of the solutions is probably wrong.
CodePudding user response:
enumerate
has two parameters, an iterable and a start.
When you write enumerate( y[:-1], 1 )
two things happen:
You are giving a chopped of copy of the
y
array to the for loop ( you chopped of the last element of the array ), but in your for loop, you actually working on the realy
array, which is not chopped of. If you set youry
toy = y[:-1]
before the for loop and give that to the enumerate (enumerate( y, 1 )
) you will see alist is out of index
error.When you give the enumerate a 1 as a starting number, you are actually skipping the first element of your real
y
array (array index starts at 0, and you are starting with ay[1]
in your for loop). Because of that ( and because of the 1. point ) you will reach the last element of the realy
array.
CodePudding user response:
enumerate
accepts an optional argument that allows us to specify the starting index of the counter. So when you do :
enumerate(y[:-1],1)
instead of :
enumerate(y)
you are just shift your index:
0 None
1 None
2 1
3 2
4 None
...
vs
1 None
2 None
3 1
4 2
5 None
...
And to conclude, given that your input is a list
, and that you add an index using enumerate
, BUT your output is a list without any index, obviously you cannot see any difference.
CodePudding user response:
In python when you have a list x and you do x[:-1] you are creating a new list without the last element. You ask for a rationale but I really cannot see how adding this would help in any way.
The fact that you start the enumerate on 1 in the second example can give you some weird behaviour
If you try the following list:
x = [None, None, 1, 2, None, None, 3, 4, None, 5, None, 6]
You will get the next two results:
[6, 6, 1, 2, 2, 2, 3, 4, 4, 5, 5, 6]
[None, None, 1, 2, 2, 2, 3, 4, 4, 5, 5, 6]
This happens since the enumerate starts on 1 so you ignore y[0] = y[-1]