# Indexing nested list with another list

So I'm wanting to index the sublists within a list using another list. So I have

x = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}


And I want the 2nd term of the first sublist, 1st term of the 2nd sublist, 3rd term of the 3rd sublist, i.e. I want output {2,4,9} or {{2},{4},{9}}

This is a simple example of a generalised problem, where x might be several thousand elements long with each element being a list with thousands of elements, and I might want to use a function like 'Take' instead of indexing, e.g. I might want to take the first 2 terms of the first list, the first term of the second list and the first 3 terms of the 3rd list to get the output {{1,2},{4},{7,8,9}}.

I have discovered the Thread function, which gives the following:

In:= Thread[g[{1, 2, 3}, {2, 1, 3}]]
Out= {g[1, 2], g[2, 1], g[3, 3]}


Therefore, I figured if I define f as follows

f[p_, q_] := x[[p, q]];


I would be able to write

Thread[f[{1, 2, 3}, {2, 1, 3}]]


And return the value obtained by evaluating

{f[1, 2], f[2, 1], f[3, 3]}


Which is {2,4,9} as I require.

Indeed, Mathematica gives

In:= {f[1, 2], f[2, 1], f[3, 3]}
Out= {2, 4, 9}


But

In:= Thread[f[{1, 2, 3}, {2, 1, 3}]]
Out= {{2, 5, 8}, {1, 4, 7}, {3, 6, 9}}


Why is this happening? Why doesn't my method work? Is there a better way?

Many thanks,

H

• Depth of your list is not 3. So f [1,2,3] doesn't make sense – OkkesDulgerci Jan 5 '18 at 13:08
• Apply is probably not what you want here, but nevertheless: x[[##]] & @@@ Transpose[{Range@Length@x, {;; 2, 1, 1 ;;}}] -> {{1, 2}, 4, {7, 8, 9}} – user1066 Jan 5 '18 at 14:57

Why is this happening?

MapThread takes the function and its arguments separately.

So you can wrap the first argument of Thread with Unevaluated to prevent evaluation before threading and get the desired result:

Thread[Unevaluated@f[{1, 2, 3}, {2, 1, 3}]]


{2, 4, 9}

Also

MapThread[f, {{1, 2, 3}, {2, 1, 3}}]
Inner[f, {1, 2, 3}, {2, 1, 3}, List]
MapIndexed[x[[#2[], #]] &, {2, 1, 3}]
f @@@ Thread[{{1, 2, 3}, {2, 1, 3}}]
f @@@ Transpose[{{1, 2, 3}, {2, 1, 3}}]
Extract[x, MapIndexed[{#2[], #} &, {2, 1, 3}]]


{2, 4, 9}

Since

f[{1, 2, 3}, {2, 1, 3}]


{{2, 1, 3}, {5, 4, 6}, {8, 7, 9}}

You get

Thread[{{2, 1, 3}, {5, 4, 6}, {8, 7, 9}}]


{{2, 5, 8}, {1, 4, 7}, {3, 6, 9}}

Instead you could use MapThread or Diagonal

Diagonal[Transpose[x][[{2, 1, 3}]]]    (* or Diagonal[x[[All, {2, 1, 3}]]] *)
MapThread[#[[#2]] &, {x, {2, 1, 3}}]
MapThread[#[[;; #2]] &, {x, {2, 1, 3}}]


{2, 4, 9}
{2, 4, 9}
{{1, 2}, {4}, {7, 8, 9}}