31
$\begingroup$

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?

$\endgroup$

6 Answers 6

43
$\begingroup$

The easiest way is probably something like this

{x, y} /. list
$\endgroup$
5
  • 5
    $\begingroup$ You are the minimalist king with maximal kingdom!! $\endgroup$ Commented Sep 12, 2012 at 16:28
  • 1
    $\begingroup$ +1 - This looks like the right solution; shorter doesn't seem possible, and now I see it it makes sense. It just didn't come up in my mind :-( Thanks. $\endgroup$
    – stevenvh
    Commented Sep 12, 2012 at 16:31
  • $\begingroup$ @PlatoManiac that's Queen, FYI. ;-) $\endgroup$
    – Mr.Wizard
    Commented Jan 14, 2013 at 10:58
  • $\begingroup$ @Mr.Wizard I deciphered that fact recently. Thx anyways though..;) $\endgroup$ Commented Jan 14, 2013 at 11:22
  • $\begingroup$ This method is nice and quick, but just to clarify a distinction which may depend on your use case: {x, y} /. {} returns {x, y} while {}[[;;, ;;, 2]] returns {} (from kguler's answer). $\endgroup$
    – user55405
    Commented May 24, 2019 at 12:39
19
$\begingroup$

Four brackets:)

list[[All, All, 2]]

or

list[[;; , ;; , 2]]
$\endgroup$
1
  • $\begingroup$ I like your method! $\endgroup$
    – yulinlinyu
    Commented Sep 13, 2012 at 3:46
19
$\begingroup$

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!

$\endgroup$
2
  • 5
    $\begingroup$ 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 $\endgroup$
    – rm -rf
    Commented Sep 12, 2012 at 17:08
  • $\begingroup$ 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. :-) $\endgroup$
    – stevenvh
    Commented Sep 12, 2012 at 17:21
14
$\begingroup$

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
$\endgroup$
5
$\begingroup$

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?

$\endgroup$
2
$\begingroup$

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}}]
$\endgroup$
1
  • 1
    $\begingroup$ This no longer works in 10.0.1 or later. $\endgroup$
    – Mr.Wizard
    Commented May 12, 2015 at 10:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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