2
$\begingroup$

I define this list:

list={{100,100},{200,200}}

Taking the transpose like this works as intended:

Transpose[list]

Taking the transpose like this yields an error message saying "Transpose::nmtx: The first two levels of {100,100} cannot be transposed.":

Map[Transpose[#]&, list]

Why aren't these two ways of taking the transpose equivalent? I've looked at the documentation on Map, but I can't figure out why the latter doesn't work. It looks like it should simply take list and put it where the # is, yet it doesn't.

$\endgroup$
4
  • 1
    $\begingroup$ You can do Map[Transpose, list, {0}] $\endgroup$ Apr 11 '20 at 12:34
  • $\begingroup$ Related: mathematica.stackexchange.com/questions/45972/… $\endgroup$
    – Michael E2
    Apr 11 '20 at 14:32
  • $\begingroup$ Transpose[#]& can be simplified as Transpose. $\endgroup$
    – wuyudi
    Apr 11 '20 at 16:07
  • 1
    $\begingroup$ No, Map[Transpose[#]&, list] takes each entry of the list, puts it where the # is and wraps the resulting sequence with { }. $\endgroup$ Apr 11 '20 at 20:31
11
$\begingroup$

Map will iterate over the list and apply some function element-wise. In your case, list is a 2D-array, so Map will iterate over the the elements of list, which are {100,100} and {200,200}. These are the values that are then applied to Transpose, which will clearly fail.

To better illustrate this, you can use some undetermined function f to see what's going on:

Clear[f]
Map[f[#] &, list]
(* {f[{100, 100}], f[{200, 200}]} *)

Replacing f with Transpose would then give

{Transpose[{100, 100}], Transpose[{200, 200}]}

which results in an error.


Edit: As Chris mentioned in the comments, this behavior can be controlled by the level spec. By, default, Map will map at the "first" level, which in the case of a 2D array like here, means that the mapped elements are lists themselves. However, if you use

 Map[Transpose, list, {0}]

this forces Map to only map elements on the "zeroth" level, which means the whole expression. This would be equivalent to

 Transpose[list]

If you use level 2, Map would go over every element in the 2D array like this:

 Map[f, list, {2}]
 (* {{f[100], f[100]}, {f[200], f[200]}} *)
$\endgroup$
3
$\begingroup$

An explanation of the description:

Transpose[list] transposes the first two levels in list.

If Transpose is applied at level $n$, then levels $n+1$ and $n+2$ are transposed, if the expression has a suitable structure: The expression must have levels $n+1$ and $n+2$, and the levels must form a "rectangular array" structure (e.g., a list of equal-length lists).

Transpose[list] applies Transpose at level 0 and transposes levels 1 and 2.

Transpose /@ list (or Map[Transpose[#]&, list]) applies Transpose at level 1 and transposes levels 2 and 3.

The OP's list has only two levels, so the second code results in an error.


The FullForm of list has the following level structure:

(*          level        0 *)
List[    (* level      1 | *)
  List[  (* level    2 | | *)
    100,100       (* 2 | | *)
  ],              (*   1 | *)
  List[  (* level    2 | | *)
    200,200       (* 2 | | *)
  ]               (*   1 | *)
]                 (*     0 *)

Every expression has a level structure of some sort. It's not easy to see the rectangular-array structure in FullForm. It may be visualized like this:

List
  ↓
 List ⟶  100 ⟶  100
  ↓
 List ⟶  200 ⟶  200

Transpose[list] restructures the expression like this:

List ⟶  List ⟶ List
           ↓        ↓
          100      100
           ↓        ↓
          200      200
$\endgroup$

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