8

I recently upgraded from Mathematica 6 to the most recent version. In my new version the Position function returns strange results that were not present in the old version. An example:

testvec = {1, 0, -1, 0, 0, 1, 0}
(* {1, 0, -1, 0, 0, 1, 0} *)

Position[testvec, Except[0]] (* {{0}, {1}, {3}, {6}, {}} *)

Why has the mysterious {0} appeared at the beginning and {} at the end? These spurious additions mess up my earlier code.

xzczd
  • 65,995
  • 9
  • 163
  • 468
Peter
  • 81
  • 1
  • 3
    BTW, Extract[testvec, %], where % denotes the results of Position, shows you what parts matched. – Michael E2 Sep 12 '20 at 19:19
  • The result is also {{0}, {1}, {3}, {6}, {}} in v6.0: https://i.stack.imgur.com/oBN1z.png Which version and OS are you in? Can you share a screenshot of the result? – xzczd Sep 14 '20 at 01:59
  • Just tested in v5.2, the result is still {{0}, {1}, {3}, {6}, {}}: https://i.stack.imgur.com/MvF2w.png Are you sure you're in v5.2? – xzczd Sep 16 '20 at 11:50

3 Answers3

11

The behavior was enhanced in later versions. You need to use in your case

Position[testvec, Except[0], {1}, Heads -> False]

to match your old version behavior.

The current behavior, in your case, results in the example output because

  • Head of $testvec$ meets condition, and head is position 0.
  • The nonzero elements match the condition, positions 1,3, and 6.
  • The whole list $testvec$ matches the condition, and has no "position".
ciao
  • 25,774
  • 2
  • 58
  • 139
6

I looked at the documentation for Position in Mathematica 6 and the corresponding documentation for Mathematica 12. I was not expecting (based on your description of the output) to find this in the Mathematica 6 docs:

The default level specification for Position is {0, Infinity}, with Heads->True.

but I did. I'm surprised that you're not seeing the same behavior in Mathematica 6 as in Mathematica 12 because Heads -> True means that the head of the expression List, which is position {0}, should be one of the parts that Position checks against the pattern. Since List is not 0, it should return {0} as a position.

This is also in both the Mathematica 12 and the Mathematica 6 documentation:

A part specification {} returned by Position represents the whole of expr.

Since, according to the first quote, the default level specification is {0, Infinity} and level 0 is the whole expression, and the whole expression is not 0, I would expect it to return {}.

So I cannot tell you why it didn't work that way in Mathematica 6, I think it should have. As a workaround, you might use the following:

Position[testvec, Except[0], {1, Infinity}, Heads -> False]
C. E.
  • 70,533
  • 6
  • 140
  • 264
2

Have a look at the documentation of the built-in Position in the section Possible issues, Position looks for matches based on patterns, which may not be the same as numerical equality:

Position[testvec, n_ /; n != 0]

({{1}, {3}, {6}})

Steffen Jaeschke
  • 4,088
  • 7
  • 20