In version 10.4.1 (Win 7 Ent) I am implementing an algorithm that needs to update a list after each pass. I initially coded this with Nothing
by removing items in the list that where no longer needed after each processing pass. This did not result in the expected outcome and I eventually sourced the error to the use of Nothing
. A very minimal example follows.
SeedRandom[19384];
datN = RandomInteger[{1, 5}, 10]
(* {2, 1, 3, 5, 1, 2, 5, 2, 2, 2} *)
For this minimal example FirstPosition[5]@datN
will represent the index of the item that needs to be removed after each processing pass. (I'm not trying to delete all 5's in the real code.) There are two 5
's. I would expect the first in position 4 to be removed at the end of the first pass.
datN[[Echo@First@FirstPosition[5]@datN]] = Nothing;
datN
>> 4
(* {2, 1, 3, 1, 2, 5, 2, 2, 2} *)
Success! The first pass finds the first 5
, removes it, and updates datN
. Or does it? Lets try the second pass which should remove the 5
in position 6.
datN[[Echo@First@FirstPosition[5]@datN]] = Nothing;
datN
>> 6
(* {2, 1, 3, 1, 5, 2, 2, 2} *)
What has happened here? The correct position of 6 was identified but instead of removing the 5
there it removed the 2
in position 5. Let us try one more time to remove the 5
now in position 5.
datN[[Echo@First@FirstPosition[5]@datN]] = Nothing;
datN
>> 5
(* {2, 1, 3, 5, 2, 2, 2} *)
It has done it again. The correct position of 5 has been identified but the 1
in position 4 has been removed instead.
Now it gets interesting. On the fourth try and every subsequent try after the fourth it simply refuses to remove anything.
datN[[Echo@First@FirstPosition[5]@datN]] = Nothing;
datN
>> 4
(* {2, 1, 3, 5, 2, 2, 2} *)
The output above will repeat with the datN
never being altered from the forth try onwards. Very odd.
Have I completely missed something or is this a bug? If so, is it still around in version 11?
Update
Clearly I have to live with it as it is. However, at this moment, I don't feel it is intuitively correct. I would understand the hold behavior if I used SetDelayed
but having used Set
it seems a reasonable expectation that the Nothing
s be removed. At least I understand its mechanism. I am dating myself a bit here but I was expecting a ReDim Preserve
type of behavior. 10 Internet points to anyone that gets that reference without looking it up.
Trace[datN[[Echo@First@FirstPosition[5]@datN]] = Nothing, TraceInternal -> True]
after doing all these steps. There is a{2, 1, 3, Nothing, Nothing, Nothing, 5, 2, 2, 2}
in it. $\endgroup$Nothing
in the documentation.Nothing
should be removed fromList
.datN
is a list. In addition, there are noHold*
attributes ondatN
. $\endgroup$Nothing
. This question will remain as a guidepost, but if desirable someone may wish to edit the original question to includeNothing
as well. $\endgroup$