3
$\begingroup$

I am in trouble with Position, Although my example works as expected it throws a warning.

Position[{{a,b},{a,c},{a,b}}, _?(#[[2]]==b&), {1}]

During evaluation of In[23]:= Part::partd: Part specification List[[2]] is longer than depth of object. >>

  (*Out[23]= {{1},{3}}*)

Whats wrong here (MMA 7) ?

Ok, have just realized that adding Heads->False helps

Position[{{a,b},{a,c},{a,b}}, _?(#[[2]]==b&), {1}, Heads->False]

But why is this necessary I allready have specifyed a levelspec of {1} so the Head should be ommited anyway.

Regards Robert

$\endgroup$
  • 1
    $\begingroup$ From Mathematica Help: With the default option setting Heads->True, Position includes heads of expressions, and their parts. BTW, the answer given by @YvesKlett will not produce such warning. $\endgroup$ – hengxin Dec 2 '14 at 7:31
  • 1
    $\begingroup$ @hengxin I removed my comment because it was not answering the question, but for the record: Position[{{a, b}, {a, c}, {a, b}}, {_, b}] or keeping the levelspec similar Position[{{a, b}, {a, c}, {a, b}}, {_, b},{1}]. $\endgroup$ – Yves Klett Dec 2 '14 at 7:38
  • $\begingroup$ Welcome to Mathematica.SE! I suggest the following: 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Read the faq! 3) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! $\endgroup$ – Michael E2 Dec 2 '14 at 23:58
3
$\begingroup$
Position[{{a, b}, {a, c}, {a, b}}, _?(#[[2]] == b &), {1}, 
 Heads -> False]

The default option is Heads-> True, which means that _?(#[[2]] == b &) is applied to the head of {{a, b}, {a, c}, {a, b}}, that is to say List

Why is _?(#[[2]] == b &) applied to the Head in your example ? : because the Head is at level {1}

By convention in Mathematica, the Head of a expression exp is exp[[0]].
exp[[0]] is at level {1}, because exp[[0]] has only one indice.

$\endgroup$
  • $\begingroup$ Ok, but why is this neccessary? I have specifyed levelspec of {1} that should be sufficient or ? $\endgroup$ – Robert Dec 2 '14 at 7:31
  • $\begingroup$ By convention in Mathematica, the Head of a expression exp is exp[[0]] $\endgroup$ – andre314 Dec 2 '14 at 7:40
  • $\begingroup$ yes, I know but I explicitly specifyed {1} as levelspec so the Head should not be toched anyway $\endgroup$ – Robert Dec 2 '14 at 8:37
  • $\begingroup$ The Head options seems to be separate from the levelspec specification. BTW it works the same in Cases when the option is set: Cases[{{a, b}, {a, c}, {a, b}}, _?(#[[2]] == b &), {1}, Heads -> True] $\endgroup$ – Chris Degnen Dec 2 '14 at 9:03
1
$\begingroup$

Ok got now the final explanation from Markus van Almsick

As the Head of an Expression needs not to be an plain Symbol (e.g. List) in aprticular the Head of an Expression can by it self be an (complicated) Expression the levelspec must and will apply also to the Head. therefore the Head must be "turned off" for simple cases

very tricky.

Regards Robert

$\endgroup$
0
$\begingroup$

Ok finaly figured out the "best" solution:

needs no Heads option and no levelspec.

Position[{{a, b}, {a, c}, {a, b}}, {_, _?(#==b &)}]

thx for all posts

$\endgroup$
  • 2
    $\begingroup$ Whats wrong with Position[{{a, b}, {a, c}, {a, b}}, {_, b}]? $\endgroup$ – Yves Klett Dec 2 '14 at 8:31
  • 1
    $\begingroup$ @Robert, look at Yves Klett comment. his solution is better than this one:) $\endgroup$ – Algohi Dec 2 '14 at 8:31
  • $\begingroup$ Hi the example was just a simplification of my real problem: actualy I want to compare a scalare to the Norm of the second list pair. indta[[Flatten@Position[dta, {_, _?(Norm@# <= tol &)}]]] $\endgroup$ – Robert Dec 2 '14 at 8:33
  • $\begingroup$ Also note that, if, say, b = 0, a pattern {_, b} will not match {a, 0.} but the pattern test {_, _?(# == b &)} will match it. Also if b = 1. - 10^-15, {a, 1.} will match {_, _?(# == b &)} but not {_, b}. So there are some differences when working with numeric expressions. $\endgroup$ – Michael E2 Dec 2 '14 at 23:57
0
$\begingroup$

This problem can easily appear with elements that are not heads, therefore Heads -> False is not a complete solution:

Position[{{a, b}, {a, c}, {a, b}, d}, _?(#[[2]] == b &), {1}, Heads -> False]

Part::partd: Part specification d[[2]] is longer than depth of object. >>

{{1}, {3}}

So long as the unevaluated form e.g. d[[2]] will not result in a false match in your test this message could be ignored, and silenced with Quiet. More robustly simply check that the Length of the element is long enough before attempting the extraction:

Position[{{a, b}, {a, c}, {a, b}, d}, _?(Length[#] >= 2 && #[[2]] == b &), {1}]
{{1}, {3}}

One can also use a more specific pattern such as:

Position[{{a, b}, {a, c}, {a, b}, d}, {_, __}?(#[[2]] == b &), {1}]

Position[{{a, b}, {a, c}, {a, b}, d}, {_, _?(# == b &), ___}, {1}]

Position[{{a, b}, {a, c}, {a, b}, d}, {_, x_ /; x == b, ___}, {1}]
$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.