3
$\begingroup$

Is there a way to directly access the elements without evaluating the whole list?

The Part function used to extract some elements in a list always evaluate the whole list first, instead of directly access to the desired elements. This is very inefficient when we are trying to extract a small set of elements from a large list because Mathematica will try to evaluate all the elements in the large list before extracting what we want. The situation is more severe in the case when some of the elements contain unevaluated expressions such as Integrate which does not converge, Mathematica will try to evaluate the unevaluated expression again even though the elements you want do not include those unevaluated expressions.

Edit: Specific example A specific example is this:

list = Table[NIntegrate[p/Sqrt[(p Cos[t])^2 + (0.2 p Sin[t] - i)^2], {p, 0, 1}, {t, 0, 2 \[Pi]}], {i, 0.01, 0.2, 0.01}]
list[[1]]

NIntegrate doesn't return a specific value when i = 0.1 and i = 0.15. But when I try to access the first element, Mathematica tried to evaluate the whole list again giving the warning message as well as taking longer time to access the element. The expected behavior should be that it evaluates just the desired element of the list, instead of evaluating again the whole list.

So is there a way to directly access the elements without evaluating the whole list?

Thank you.

$\endgroup$
  • 1
    $\begingroup$ Please give a code example. $\endgroup$ – Henrik Schumacher Nov 26 '17 at 9:05
  • 3
    $\begingroup$ How is the list created in the first place? How are the elements not evaluated when you create the list? $\endgroup$ – Marius Ladegård Meyer Nov 26 '17 at 9:55
3
$\begingroup$

It is unclear what keeps your list unevaluated in the first place. To learn about evaluation control, I suggest reading Working with Unevaluated Expressions.

Here is an example of maintaining a list of elements in unevaluated form, and extracting one with or without evaluation.

list = Hold[Echo[1], Echo[2], Echo[3]]
(* Hold[Echo[1], Echo[2], Echo[3]] *)

list[[2]]    
>> 2
(* 2 *)

Extract[list, 2]    
>> 2
(* 2 *)

list[[{2}]]
(* Hold[Echo[2]] *)

Extract[list, 2, Hold]
(* Hold[Echo[2]] *)
$\endgroup$
3
$\begingroup$

You could use OwnValues:

Extract[OwnValues[list],{1,2,1}]

12.0596

$\endgroup$
  • $\begingroup$ That's actually really clever! I'm going to remember that one. $\endgroup$ – Sjoerd Smit Nov 27 '17 at 9:49

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.