34
$\begingroup$

Starting from these two lists,

var = {a, b, c} 
values = {{1, 2, 3}, {4, 5, 6}, {7, 8 , 9}}

how can I generate a list of rules?

rules = {{a -> 1, b -> 2, c -> 3}, {a -> 4, b -> 5, c -> 6}, {a -> 7, b -> 8, c -> 9}}

This is how far I have got

In: {{a, b, c}, {1, 2, 3}} // Transpose
In: Rule @@@ %
Out: {{a, 1}, {b, 2}, {c, 3}}
Out: {a -> 1, b -> 2, c -> 3}
$\endgroup$

6 Answers 6

31
$\begingroup$

Another way:

Thread[var -> #] & /@ values
$\endgroup$
2
  • 4
    $\begingroup$ Cleaner: Thread[var -> #] & /@ values $\endgroup$
    – Mr.Wizard
    Mar 16, 2012 at 9:51
  • $\begingroup$ @Mr.Wizard Okay. $\endgroup$
    – Szabolcs
    Mar 16, 2012 at 10:06
27
$\begingroup$

I propose using Inner:

Inner[Rule, var, values\[Transpose], List]

This is faster than other methods presented:

SetAttributes[timeAvg, HoldFirst]

timeAvg[func_] := 
  Do[If[# > 0.3, Return[#/5^i]] & @@ Timing @ Do[func, {5^i}], {i, 0, 15}]

var = Range@70;
values = Array[Times, {500, 70}];

Inner[Rule, var, values\[Transpose], List]; // timeAvg
Map[Rule @@@ Transpose[{var, #}] &, values]; // timeAvg
Thread[var -> #] & /@ values; // timeAvg
MapThread[Rule, {var, #}] & /@ values; // timeAvg
0.009736

0.01248

0.01372

0.01248
$\endgroup$
7
  • $\begingroup$ Would you mind editing in the definition of timeAvg? $\endgroup$
    – Yves Klett
    Mar 16, 2012 at 9:25
  • $\begingroup$ @Yves I put at link at the bottom; is that good enough? $\endgroup$
    – Mr.Wizard
    Mar 16, 2012 at 9:26
  • 1
    $\begingroup$ Sure! Perhaps for the casual sloppy Paste&Evaluate user (i.e. me) actually putting it in would be more convenient. $\endgroup$
    – Yves Klett
    Mar 16, 2012 at 9:32
  • 1
    $\begingroup$ @Yves done as requested. $\endgroup$
    – Mr.Wizard
    Mar 16, 2012 at 9:44
  • $\begingroup$ Still another possibility: Inner[#2 -> #1 &, values, var, List] $\endgroup$ Oct 27, 2012 at 2:08
15
$\begingroup$

Just do a map on the values, like this:

var = {a, b, c}
values = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
Map[Rule @@@ Transpose[{var, #}] &, values]

This is the output: {{a -> 1, b -> 2, c -> 3}, {a -> 4, b -> 5, c -> 6}, {a -> 7, b -> 8, c -> 9}}

(In your question you have c->5, but I'm assuming this is a mistake:)

$\endgroup$
1
  • 1
    $\begingroup$ I would use Thread[var -> #]&, or Thread[ Rule[ var, # ]]&, if you prefer, as the function being mapped. It accomplishes the same thing with less code. I'd even be tempted to rewrite it as Thread[var -> #]& /@ values to take advantage of the shorthand notation. $\endgroup$
    – rcollyer
    Mar 16, 2012 at 19:19
14
$\begingroup$

Another alternative:

MapThread[#1 -> #2 &, {var, #}] & /@ values

or, equivalently

MapThread[Rule, {var, #}] & /@ values
$\endgroup$
6
$\begingroup$

Just for fun, another alternative using Outer:

Flatten[Outer[Thread[#1 -> #2] &, {var}, values, 1], 1]
$\endgroup$
3
$\begingroup$
AssociationThread[var, #] & /@ values // Normal

{{a->1,b->2,c->3},{a->4,b->5,c->6},{a->7,b->8,c->9}}


Just for record

GeneralUtilities`AssociatePairs[Transpose[{var, #}]] & /@ values // Normal

{{a->1,b->2,c->3},{a->4,b->5,c->6},{a->7,b->8,c->9}}

$\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.