7
$\begingroup$

I am using Mathematica 10 now.

I typed code below

{{1, 2}, {2, 4}, {3, 6}, {4, 8}}[[;; , 1]][[1]]

and this gives result

1

But code

{{1, 2}, {2, 4}, {3, 6}, {4, 8}}[[;; , 1, 1]]

gives error

Part::partd: Part specification {{1,2},{2,4},{3,6},{4,8}}[[1;;All,1,1]] is longer than depth of object. >>

But according to help doc

expr[[i,j,...]]] or Part[expr,i,j,...]] is equivalent to expr[[i]][[j]]...

What is wrong?!! I remember I always coded it like this in Mathematica 9, no error occurs. Is it a bug??

$\endgroup$
7
  • $\begingroup$ Span threads over the defined elements, which then do not have sufficient depth for the last part specification. E.g. {{1, 2}, {2, 4}, {3, 6}, {4, 8}}[[1, 1, 1]] returns the same error (on probably any version). Note: I removed the bugs tag, which is for confirmed bugs only. $\endgroup$
    – Yves Klett
    Commented Sep 1, 2014 at 12:31
  • 3
    $\begingroup$ Also from the docs: "Successive part extraction is not always equivalent to direct part extraction". Perhaps it is better to read the piece you quote from the docs with the implicit proviso: "If expr[[i,j,...]] is a valid expression, it is equivalent to ..."? $\endgroup$
    – kglr
    Commented Sep 1, 2014 at 12:31
  • $\begingroup$ Oh, and 9.01 throws the same error. $\endgroup$
    – Yves Klett
    Commented Sep 1, 2014 at 12:53
  • $\begingroup$ @kguler Oh, such a delicate definition. Probably you are right. $\endgroup$
    – matheorem
    Commented Sep 1, 2014 at 13:07
  • $\begingroup$ @MichaelE2 hmm... I am still waiting for someone in the know to expose the innards of Part+Span evaluation. That might actually be quite useful! $\endgroup$
    – Yves Klett
    Commented Sep 1, 2014 at 17:36

2 Answers 2

8
$\begingroup$

General explanation

First, in general, a valid expr[[i1, i2,..., in]]] requires expr to have at least n levels, and the result will have n fewer levels.

The OP's example list {{1, 2}, {2, 4}, {3, 6}, {4, 8}} has two. The code

{{1, 2}, {2, 4}, {3, 6}, {4, 8}}[[;; , 1, 1]]

needs at least three levels. Hence the error.

Next, in the sentence of the documentation for Part,

expr[[i,j,...]] or Part[expr,i,j,...]] is equivalent to expr[[i]][[j]]...

the i, j, ... are to be integers, or so I used to think. However, as @kguler said in a comment, the equivalence holds if expr[[i, j,...]] is valid.

If instead of an integer, a Span or a List (or All) is used, the result will be a (possibly nested) list. Each Span and List adds a level to the depth of the result one would have had if every part had been a simple integer. This allows for further extraction of parts as in the OP's first example.

OP's first example

We can break down the OP's example as follows. The expression

{{1, 2}, {2, 4}, {3, 6}, {4, 8}}[[;; , 1]][[1]]

is equivalent to the last result of

{{1, 2}, {2, 4}, {3, 6}, {4, 8}}[[;; , 1]]
%[[1]]
(*
  {1, 2, 3, 4}
  1
*)

The first expression has a Span and evaluates to a list of parts, the first part of each expression at level 2. Adding a [[1]] extracts the first part of this list.

It may be a little easier to see what's going on in an example that gives no errors:

foo = ArrayReshape[Range@8, {4, 2, 1}]
foo[[;; , 1, 1]]
foo[[;; , 1]][[1]]
(*
  {{{1}, {2}}, {{3}, {4}}, {{5}, {6}}, {{7}, {8}}}
  {1, 3, 5, 7}
  {1}
*)

The last output is a list because {1} is the first part of

foo[[;; , 1]]
(*
  {{1}, {3}, {5}, {7}}
*)
$\endgroup$
4
  • $\begingroup$ To the down-voter: Is there an error or some other issue? $\endgroup$
    – Michael E2
    Commented Sep 2, 2014 at 20:09
  • $\begingroup$ I did not downvote your answer, I never downvote correct answers. I'm just trying to detect an individual who downvoted mine a few minutes ago. Threre are very few suspicious... $\endgroup$
    – Artes
    Commented Sep 3, 2014 at 19:05
  • $\begingroup$ @Artes All in all, it's been a considerate community, whose criticism has been carried out in a reasonably honest way. Let's hope it stays that way. $\endgroup$
    – Michael E2
    Commented Sep 3, 2014 at 19:56
  • 2
    $\begingroup$ It could be an interesting question to write an application in Mathematica finding who downvoted an answer. Comparing reputation points in collective registry of users (it subtracts points when one downvotes) with individual profiles (where points from downvoting are not registered) we can find downvoters. By using my pedestrian approach I could find only 3 suspected, but improving it with another characteristics we could approach up to $90$% certainity on average:). $\endgroup$
    – Artes
    Commented Sep 3, 2014 at 20:19
3
$\begingroup$

When using [[All, 1, 1]] you are attempting to extract the first element of the first element of all parts of the expression. Note what happens when you specify 0 instead of 1, which is a valid "part" of 1 etc.:

{{1, 2}, {2, 4}, {3, 6}, {4, 8}}[[All, 1, 0]]
{Integer, Integer, Integer, Integer}

Part 0 is the head of an expression. See: Is there a summary of answers Head[] can give?

$\endgroup$
1
  • $\begingroup$ Wow, deep understanding! Thanks, Mr. Wizard $\endgroup$
    – matheorem
    Commented Sep 3, 2014 at 0:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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