10
$\begingroup$

I have a list of lists of equal sizes (odd or even), e.g.

list={{1,-2,3,1,3,4},{3,5,6,-1,9,0},{1,-2,-4,-5,1,5},{1,-1,2,3,5,4},...} 

I would like to change signs of every element which is on even or odd position. In the example above, for the choice of change on even positions, it should give the following result:

 listnew={{1,2,3,-1,3,-4},{3,-5,6,1,9,0},{1,2,-4,5,1,-5},{1,1,2,-3,5,-4},...} 

What is the most effective way to achieve this? (The length of list may be huge here).

$\endgroup$

7 Answers 7

9
$\begingroup$

MapIndexed can not only extract positions of elements (in Slot 2, always), but also further apply transformations to the elements themselves (Slot 1). So in my opinion, it is the most suitable one to do the job desired:

MapIndexed[(-1)^(#2[[2]] + 1) # &, list, {2}] 
$\endgroup$
10
$\begingroup$

Use Part to multiply even positions by -1:

listeven = list = {{1, -2, 3, 1, 3, 4}, {3, 5, 6, -1, 9, 0}, {1, -2, -4, -5, 1, 5}, {1, -1, 2, 3, 5, 4}}; listeven[[All, 2 ;; ;; 2]] *= -1; listeven (* {{1, 2, 3, -1, 3, -4}, {3, -5, 6, 1, 9, 0}, {1, 2, -4, 5, 1, -5}, {1, 1, 2, -3, 5, -4}} *) 

A small change multiplies the odd positions:

listodd = list = {{1, -2, 3, 1, 3, 4}, {3, 5, 6, -1, 9, 0}, {1, -2, -4, -5, 1, 5}, {1, -1, 2, 3, 5, 4}}; listodd[[All, 1 ;; ;; 2]] *= -1; listodd (* {{-1, -2, -3, 1, -3, 4}, {-3, 5, -6, -1, -9, 0}, {-1, -2, 4, -5, -1, 5}, {-1, -1, -2, 3, -5, 4}} *) 
$\endgroup$
9
$\begingroup$
list = {{1, -2, 3, 1, 3, 4}, {3, 5, 6, -1, 9, 0}, {1, -2, -4, -5, 1, 5}, {1, -1, 2, 3, 5, 4}}; v = {1, -1, 1, -1, 1, -1}; Times[v, #] & /@ list Outer[Times, {v}, list, 1] // First 
$\endgroup$
8
$\begingroup$

This is one way:

MapIndexed[{n, pos} |-> If[ EvenQ @ Last @ pos, -n, n], list, {2}] 
$\endgroup$
8
$\begingroup$

This should be reasonably fast, I think:

list.DiagonalMatrix[{1,-1,1,-1,1,-1}] 

{{1, 2, 3, -1, 3, -4}, {3, -5, 6, 1, 9, 0}, {1, 2, -4, 5, 1, -5}, {1, 1, 2, -3, 5, -4}}

list.DiagonalMatrix[{1,-1,1,-1,1,-1}]==listnew 

True

Alternatively:

With[{x=Length@list[[1]]}, list.SparseArray[Band[{1, 1},{x,x}] -> {1,-1}]]==listnew 

True

where

list={{1,-2,3,1,3,4},{3,5,6,-1,9,0},{1,-2,-4,-5,1,5},{1,-1,2,3,5,4}} 
$\endgroup$
3
$\begingroup$
list = {{1, -2, 3, 1, 3, 4}, {3, 5, 6, -1, 9, 0}, {1, -2, -4, -5, 1, 5}, {1, -1, 2, 3, 5, 4}}; 

ChangeSign[m_, s_ : 2] := MapAt[-# &, m, {All, s ;; ;; 2}] 

Even positions:

ChangeSign[list] 

{{1, 2, 3, -1, 3, -4},
{3, -5, 6, 1, 9, 0},
{1, 2, -4, 5, 1, -5},
{1, 1, 2, -3, 5, -4}}

Odd positions:

ChangeSign[list, 1] 

{{-1, -2, -3, 1, -3, 4},
{-3, 5, -6, -1, -9, 0},
{-1, -2, 4, -5, -1, 5},
{-1, -1, -2, 3, -5, 4}}

$\endgroup$
1
$\begingroup$
list = {{1, -2, 3, 1, 3, 4}, {3, 5, 6, -1, 9, 0}, {1, -2, -4, -5, 1, 5}, {1, -1, 2, 3, 5, 4}}; 

Another way using Replace, Table and DiagonalMatrix:

f = DiagonalMatrix[Table[(-1)^(n + 1), {n, #[[-1]] &@Dimensions@#}]] &; Replace[#, x_ :> x . f@#, 1] &@list // TeXForm 

$\left( \begin{array}{cccccc} 1 & 2 & 3 & -1 & 3 & -4 \\ 3 & -5 & 6 & 1 & 9 & 0 \\ 1 & 2 & -4 & 5 & 1 & -5 \\ 1 & 1 & 2 & -3 & 5 & -4 \\ \end{array} \right)$

$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.