# Extract memoized results in the form of a rule

Lets say I define a function f with memoization. Is there some way to extract the memoized values?

For example,

f[0] = 1; f[1] = 5; f[20] = 42


Is there some way to get a list similar to {0 -> 1, 1 -> 5, 20 -> 42}?

Note, FullDefinition is close, but I dont know how to handle its output.

-
You may want to start by taking a look at the docs for DownValues[] –  belisarius Jun 14 at 20:58
Ah, yes, of course! I feel silly now. –  Per Alexandersson Jun 14 at 21:07

This will work more generally for memoized functions taking one integer argument.

Clear[f];
f[0] = 1;
f[x_Integer] := f[x] = f[x - 1] + 1/x
f /@ Range[3];
Cases[DownValues[f], f[i_Integer] :> Rule[i, f[i]], Infinity]

{0 -> 1, 1 -> 2, 2 -> 5/2, 3 -> 17/6}

-
f[0] = 1; f[1] = 5; f[20] = 42;

Rule @@@
Partition[
Cases[DownValues[f], _Integer, Infinity],
2]


{0 -> 1, 1 -> 5, 20 -> 42}

-
extremely nice ! –  eldo Jun 14 at 21:41
@eldo Thanks. In your approach, use Identity rather than Sequence. –  Bob Hanlon Jun 14 at 21:56
I like this, but there is a problem with it. Although it works for the OP's example date, it won't work for a memoized function like f[0] = 1; f[x_Integer] := f[x] = f[x - 1] + 1/x. –  m_goldberg Jun 14 at 22:13

For this particular situation the following is an alternative and since no Pattern matching is being done here, it is slightly faster than the Cases solutions provided.

makeFRule[func_, start_, end_] := MapThread[Rule, Rest @ Extract[DownValues[func][[start ;; end]],
{{0}, {All, 1, 1, 1}, {All, 1, 1}}]]


Test data:

lis = Transpose[{Range[10^6], RandomInteger[10, 10^6]}];
(f[#1] = #2) & @@@ lis; (* create DownValues *)


Timings:

rule1 = makeFRule[f, 1, -1]; // AbsoluteTiming
rule2 = Cases[DownValues[f], f[i_Integer] :> Rule[i, f[i]], Infinity]; //
AbsoluteTiming
rule1 == rule2

(*
8.852543
10.243611
True
*)

-