30
$\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$
28
$\begingroup$

Another way:

Thread[var -> #] & /@ values
$\endgroup$
  • 4
    $\begingroup$ Cleaner: Thread[var -> #] & /@ values $\endgroup$ – Mr.Wizard Mar 16 '12 at 9:51
  • $\begingroup$ @Mr.Wizard Okay. $\endgroup$ – Szabolcs Mar 16 '12 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$
  • $\begingroup$ Would you mind editing in the definition of timeAvg? $\endgroup$ – Yves Klett Mar 16 '12 at 9:25
  • $\begingroup$ @Yves I put at link at the bottom; is that good enough? $\endgroup$ – Mr.Wizard Mar 16 '12 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 '12 at 9:32
  • 1
    $\begingroup$ @Yves done as requested. $\endgroup$ – Mr.Wizard Mar 16 '12 at 9:44
  • $\begingroup$ Still another possibility: Inner[#2 -> #1 &, values, var, List] $\endgroup$ – J. M. will be back soon Oct 27 '12 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
    $\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 '12 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.