# How to take and evaluate a specific part of a list without evaluating the rest?

I have a large list, for example,

lis = {x + y, x y, Sin[x] y + Exp[y], x^2 y}


and its elements depend on variables x and y. Later I assign numerical values to x and y

x = {1, 2, 3, 4, 5}
y = {3, 4, 5, 6, 7}


If I run

lis[]


(which is Part[lis, 1]), the whole list lis will be evaluated, and then the first part is taken. But if the list is very large, and I only need the first element, it will waste lots of time to evaluate the rest. Is there a simple way to take and evaluate a specific part of a list without evaluating the rest?

• This could be better example: ClearAll[x, y, z, list]; list = {x, y, z}; x = 1; y = 2; z := Pause; – Kuba Nov 23 '15 at 15:24

You could map Hold over the list:-

lis = {x + y, x y, Sin[x] y + Exp[y], x^2 y};
heldlis = Map[Hold, lis];
x = {1, 2, 3, 4, 5};
y = {3, 4, 5, 6, 7};
ReleaseHold@heldlis[]


{4, 6, 8, 10, 12}

• This is the first thought that occurs in my mind:) – xyz Nov 23 '15 at 14:23
• Another possibility in case lis is very large would be to change heldlis = Map[Hold, lis] to heldlis = Hold @@ lis, and accordingly ReleaseHold@heldlis[] to heldlis[]. This proves to be faster for both the creation of heldlis and the retrieving of the sough element from the last evaluation. It also uses less memory. – user31159 Nov 24 '15 at 3:43
• @Xavier - heldlis = Hold @@ lis works ok. Then you don't need ReleaseHold; just heldlis[] will suffice. – Chris Degnen Nov 24 '15 at 8:51

Is there a simple way to take and evaluate a specific part of a list without evaluating the rest?

You could use the Rule[] rather than Set[]. For instance,

lis = {x + y, x y, Sin[x] y + Exp[y], x^2 y};

lis[] /.{x -> {1, 2, 3, 4, 5}, y -> {3, 4, 5, 6, 7}}

 {4, 6, 8, 10, 12}


If you define lis before x and y as a plain List you can use the following trick with OwnValues

ClearAll[x, y];
lis = {x + y, x y, Sin[x] y + Exp[y], x^2 y};
x = {1, 2, 3, 4, 5};
y = {3, 4, 5, 6, 7};

Part[Hold@lis /. OwnValues@lis, 1, 1]
(* {4, 6, 8, 10, 12} *)


Indeed, it calculates the first element only:

Part[Hold@lis /. OwnValues@lis, 1, 1] // Trace

(* {{{OwnValues[lis], {HoldPattern[lis] :> {x+y,x y,E^y+y Sin[x],x^2 y}}},
Hold[lis] /. {HoldPattern[lis]:>{x+y,x y,E^y+y Sin[x],x^2 y}},
Hold[{x+y,x y,E^y+y Sin[x],x^2 y}]},
Hold[{x+y,x y,E^y+y Sin[x],x^2 y}][[1,1]], x+y,
{x,{1,2,3,4,5}}, {y,{3,4,5,6,7}}, {1,2,3,4,5}+{3,4,5,6,7},
{1+3,2+4,3+5,4+6,5+7}, {1+3,4}, {2+4,6}, {3+5,8}, {4+6,10}, {5+7,12},
{4,6,8,10,12}} *)


Another way is to store each part of the list using memorization and then call the part you want.

Quit[];

i = 1; (f[i++] = #) & /@ (lis = {x + y, If[x > 0, Pause],
Sin[x] y + Exp[y], x^2 y});


Now try this and check the difference in time.

x = 1;
f;
lis[];