8
$\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$
8
$\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$
9
$\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$
8
$\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$
6
$\begingroup$

This is one way:

MapIndexed[{n, pos} |-> If[ EvenQ @ Last @ pos, -n, n], list, {2}]
$\endgroup$
5
$\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$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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