Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a set that looks like:

s = {{1, 2, 3} -> 9, {4, 1, 9} -> 9, {3, 7, 3} -> 1};

Now, I want to replace each element of the set by the lhs of "->". The result should look like this:

s = {{1, 2, 3}, {4, 1, 9}, {3, 7, 3}};

The problem:

I only want to modify the list s without creating a new list. This is why Replace[] and Map[] cannot be used in this scenario.

Thank you in advance!

share|improve this question
3  
list[[All, 1]] –  Öskå Dec 22 '13 at 13:20
    
btw. Map[First, {{1, 2, 3} -> 9, {4, 1, 9} -> 9, {3, 7, 3} -> 1}] does the job, but i want to REPLACE the elements. Thank you! –  user11284 Dec 22 '13 at 13:21
    
Replace[{{1, 2, 3} -> 9, {4, 1, 9} -> 9, {3, 7, 3} -> 1}, x_ :> First[x], {1}] ? –  andre Dec 22 '13 at 13:31
2  
Your question is not clear: Oska's answer and your Map and andres answer all accomplish the task as you've asked it. If this isn't what you want, you need to be more explicit. –  bill s Dec 22 '13 at 13:32
    
Welcome to Mathematica.SE. I agree with bill's concern; I have closed this post to answers to head off people answering the wrong question. Please clarify what you are actually trying to do. I will then reopen it. –  Mr.Wizard Dec 22 '13 at 13:37
show 4 more comments

3 Answers

You state that you want to modify the original rule list rather than creating a new list. I assume that you want to avoid copying the list for memory reasons. I think you are unlikely to do better than the simple list = list[[All, 1]] recommended by Öskå. We can see that the additional memory used is fairly small, at least with the type of sample rules you gave:

$HistoryLength = 0;

big = MapThread[Rule, {RandomInteger[9, {5*^6, 3}], RandomInteger[99, 5*^6]}];

MaxMemoryUsed[]
1614925768

After the operation:

big = big[[All, 1]];
MaxMemoryUsed[]
1700726928

Using First by comparison (in a separate kernel):

big = First /@ big;
MaxMemoryUsed[]
1940364440

Part only uses an additional ~5.3% RAM.

share|improve this answer
add comment

Another possibility, discussed several times, e.g. in passing large list by reference, is to use the "trick" of holding the argument of a function to pass it by reference.

ClearAll[f];
Attributes[f] = {HoldFirst};
f[li_] := Do[li[[i]] = First[li[[i]]], {i, Length[li]}];

f[s]

produces the desired outcome of modifying the list in place as you desired, without copying it.

share|improve this answer
add comment

Faster than First; but compared to Part, slower yet with a similar memory usage:

Block[{Rule = #1 &}, s = s]
(* {{1, 2, 3}, {4, 1, 9}, {3, 7, 3}} *)

Per Mr.Wizard's memory comparison, but with timings:

$HistoryLength = 0;

big = MapThread[
   Rule, {RandomInteger[9, {5*^6, 3}], RandomInteger[99, 5*^6]}];

MaxMemoryUsed[]
1742482672
big = big[[All, 1]]; // AbsoluteTiming
MaxMemoryUsed[]
{0.659603, Null}
1742482672
Block[{Rule = #1 &}, big = big]; // AbsoluteTiming
MaxMemoryUsed[]
{2.095955, Null}
1742482672
big = First /@ big; // AbsoluteTiming
MaxMemoryUsed[]
{5.038712, Null}
2095818904
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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