31

Mathematica has a lot of list manipulation functions, and, also because I don't work with lists often, at times I'm a bit lost. I'll find a way, but I'm sure it's not the most efficient. Case in point, this list:

list = {{x -> -1, y -> 5}, {x -> -1, y -> 6}, {x -> -1, y -> 7}, {x -> 0, y -> 2}, 
 {x -> 0, y -> 3}, {x -> 0, y -> 4}, {x -> 0, y -> 5}, {x -> 0, y -> 6},  
 {x -> 0, y -> 7}, {x -> 1, y -> 2}, {x -> 1, y -> 3}, {x -> 1, y -> 4},  
 {x -> 1, y -> 5}, {x -> 1, y -> 6}, {x -> 1, y -> 7}, {x -> 2, y -> 3}, 
 {x -> 2, y -> 4}, {x -> 2, y -> 5}, {x -> 2, y -> 6}, {x -> 2, y -> 7}, 
 {x -> 3, y -> 4}, {x -> 3, y -> 5}, {x -> 3, y -> 6}, {x -> 3, y -> 7}, 
 {x -> 4, y -> 5}, {x -> 4, y -> 6}, {x -> 4, y -> 7}, {x -> 5, y -> 6}, 
 {x -> 5, y -> 7}, {x -> 5, y -> 8}, {x -> 6, y -> 7}, {x -> 6, y -> 8}, {x -> 7, y -> 8}}  

I just need the numerical data, then this function:

Transpose[{list[[All, 1]][[All, 2]], list[[All, 2]][[All, 2]]}]

gives me the desired result, but it doesn't look good, and I'm afraid of wearing out my [ and ] keys.

{{-1, 5}, {-1, 6}, {-1, 7}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, 
 {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {2, 3}, {2, 4}, {2, 5}, 
 {2, 6}, {2, 7}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {4, 5}, {4, 6}, {4, 7}, 
 {5, 6}, {5, 7}, {5, 8}, {6, 7}, {6, 8}, {7, 8}}  

What's the best way to extract the data from the list?

Ajasja
  • 13,634
  • 2
  • 46
  • 104
stevenvh
  • 6,866
  • 5
  • 41
  • 64

6 Answers6

43

The easiest way is probably something like this

{x, y} /. list
Heike
  • 35,858
  • 3
  • 108
  • 157
19

I will do

list /. Rule[a_,b_] :> b

Though less elegant, for large lists replacement using patterns seems faster.

list = Table[{x -> RandomReal[], y -> RandomReal[]}, {i, 100000}];
list /. Rule[a_, b_] :> b; // AbsoluteTiming

{0.1530087, Null}

Heike's method

{x, y} /. list; // AbsoluteTiming

{0.3340191, Null}

The very efficient one from kguler

list[[All, All, 2]]; // AbsoluteTiming

{0.0370021, Null}

If I have to choose, {x, y} /. list all the way!

rm -rf
  • 88,781
  • 21
  • 293
  • 472
PlatoManiac
  • 14,723
  • 2
  • 42
  • 74
  • 5
    This answer is being overlooked in light of simpler solutions for the example given, but this is more general and flexible. For instance, if the list had several symbols and you didn't know which was in which sublist (e.g. list = Table[{Unique[x] -> RandomReal[], Unique[y] -> RandomReal[]}, {i, 10^6}]), yet wanted only the numerical values, then this certainly is the way to go. kguler's answer works here too, but will not for ragged lists. So +1, although I would've used :> instead of -> for the replacement because otherwise, it'll be affected by prior assignments to b – rm -rf Sep 12 '12 at 17:08
  • Thanks, Plato, for the benchmark. I also like Heike's solution best, but will keep R.M.'s comment in mind. About that extra 180 ms, well, maybe I can have a cup of coffee while I'm waiting for the result then. :-) – stevenvh Sep 12 '12 at 17:21
19

Four brackets:)

list[[All, All, 2]]

or

list[[;; , ;; , 2]]
kglr
  • 394,356
  • 18
  • 477
  • 896
14

Mathematica on the Raspberry Pi or version 10 of the software has a Values function which works with Associations and a list of rules. The simplest answer to this question is:

Values@list
rm -rf
  • 88,781
  • 21
  • 293
  • 472
5

While I would actually use list[[All, All, 2]] as I have yet to find a case where that is not fastest, you could also do this with Apply:

Apply[#2 &, list, {2}]

I take the comment about wearing out your keys as humorous, nevertheless read this:

Automating Esc [[ Esc formatting?

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
2

This undocumented form of Extract can be used and it is just as fast or slightly faster that Part on my machine:

Last @ Extract[list, {{0}, {All, All, 2}}]
RunnyKine
  • 33,088
  • 3
  • 109
  • 176