6

Here is a list:

list = {{1, 2, 3, 2, 3}, {3, 1, 1, 2, 3}, {3, 2, 1, 3, 2}, {1, 2, 1, 1, 1}};

I wish to have all elements be zero except the first and the fourth in each row: desired:

list={{1, 0, 0, 2, 0}, {3, 0, 0, 2, 0}, {3, 0, 0, 3, 0}, {1, 0, 0, 1, 0}};

I have written:

Do[
  Do[
     If[Position[list, list[[i, j]]] != {i, 1} && 
      Position[list, list[[i, j]]] != {i, 4}, list[[i, j]] = 0]
     , {i, 1, 4}]
    ,{j, 1, 5}]

But it doesn't work correctly. Is there any way to reach this goal?

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
Unbelievable
  • 4,847
  • 1
  • 20
  • 46

2 Answers2

6
list.DiagonalMatrix[{1, 0, 0, 1, 0}]

or

Inner[Times, list, {1, 0, 0, 1, 0}, List] // MatrixForm

$$\left( \begin{array}{ccccc} 1 & 0 & 0 & 2 & 0 \\ 3 & 0 & 0 & 2 & 0 \\ 3 & 0 & 0 & 3 & 0 \\ 1 & 0 & 0 & 1 & 0 \\ \end{array} \right)$$

Edit

It may also be done as follows using Inner (see here):

Inner[Times, list, DiagonalMatrix[{1, 0, 0, 1, 0}]] // MatrixForm

 

With Dot and SparseArray:

list.SparseArray[{ {1, 1} -> 1, {4, 4} -> 1}, {5, 5}] // MatrixForm

In 'pseudocode':

newmat = oldmat.SparseArray[{ {<col-position-old>, <col-position-new>} -> 1,
          ...}, {< total-cols-old >, <total-cols-new>}]

 

For example, to create a new list with col-1-old -> col-4-new, col-4-old -> col-1-new, col-3-old -> col-2-new, and entries in all other columns equal to zero:

list1 // #.SparseArray[{ {1, 4} -> 1, {4, 1} -> 1, {3, 2} -> 
   1}, {Dimensions[#][[2]], 5}] & // MatrixForm

$$ \left( \begin{array}{ccccc} 2 & 3 & 0 & 1 & 0 \\ 2 & 1 & 0 & 3 & 0 \\ 3 & 1 & 0 & 3 & 0 \\ 1 & 1 & 0 & 1 & 0 \\ \end{array} \right)$$

user1066
  • 17,923
  • 3
  • 31
  • 49
5

To preserve the original list you could do

 res = list;
 res[[All, {2, 3, 5}]] = 0;
 res // MatrixForm

Or

MapAt[0&, list, {All, {2, 3, 5}}] // MatrixForm

Or (thanks @kglr)

ReplacePart[list, {{_, 2 | 3 | 5} -> 0}] // MatrixForm

All give

enter image description here

eldo
  • 67,911
  • 5
  • 60
  • 168