# Select an element from each matrix row/column specified by a vector

Let's say we have a matrix (or an arbitrary 2+D list) x and an integer vector l of the same length. What is the most elegant way to get a list {x[[1,l[[1]]]], x[[2, l[[2]]]],...}? The best solution I can think about is

x[[#, l[[#]]]]&/@Range@Length@x


, but I'm sure there should be a much easier/more elegant way.

• Can you give an example of list x and vector l? It's not completely clear to me what "l" is. It also seems to me that l needs an additional condition, i.e. it's elements must be less or equal then the 2+D dimension of the matrix Commented Jul 2, 2018 at 10:59
• x is an arbitrary matrix, e.g. x = RandomReal[{0., 1.}, {3, 3}]. l is a list of integers with the same length as x, e.g. l={1,2,2}. Yes, this additional condition is required if we want the code to be evaluated without errors.
– Ihor
Commented Jul 2, 2018 at 11:03

This might not be the most elegant way to do that, but it is descently efficient to use Extract:

m = 1000;
n = 2000;
x = RandomReal[{-1, 1}, {m, n}];
l = RandomInteger[{1, n}, m];

a = x[[#, l[[#]]]] & /@ Range@Length@x; // AbsoluteTiming // First
b = Flatten@MapIndexed[x[[#2, #1]] &, l]; // AbsoluteTiming // First
c = Extract[x, Transpose[{Range[Length[l]], l}]]; // AbsoluteTiming // First
a == b == c


0.140761

0.002416

0.000067

True

MapIndexed[x[[#2, #1]] &, l]


An example:

SeedRandom[90]; x = RandomReal[{0., 1.}, {3, 3}]
l = {1, 2, 2};
MapIndexed[x[[#2, #1]] &, l]


{{0.647385, 0.307327, 0.702473}, {0.656437, 0.675096, 0.0759657}, {0.733796, 0.139355, 0.0910026}}

{{0.647385}, {0.675096}, {0.139355}}

MapThread[#1[[#2]]&, {x,l}]


or equivalently

MapThread[
With[{f = #1, x = #2},
Construct[f[[#]] &, x]] &, {x, l}]


With ReplacePart

list = {{9, 7, 8}, {3, 9, 4}, {8, 2, 5}};
p = {1, 2, 2};

ReplacePart[x, i_ :> list[[i, p[[i]]]]]


{9, 9, 2}