7
$\begingroup$

Say a list list={{1,2},{3,4}}, list[[1]] and list[[2]] works. But list[[3]] gives an error of

Part::partw: Part 3 of {{1,2},{3,4}} does not exist.

This is alright, since there's no part 3 indeed. But what if I wish to handle that error. So in this case, I want to return empty list {} if the part-does-not-exist error happens.

I try to refer to https://reference.wolfram.com/language/ref/Catch.html, but it seems to be involved with Throw. Therefore I try to think of a simpler scenario as above.

$\endgroup$
4
  • 2
    $\begingroup$ Have you seen Indexed[]? $\endgroup$ – J. M.'s ennui Mar 21 '20 at 10:29
  • 1
    $\begingroup$ Indexed[list,3] would also give error. $\endgroup$ – liang Mar 21 '20 at 11:19
  • $\begingroup$ +1 for it's a good mentioning. $\endgroup$ – liang Mar 21 '20 at 11:42
  • $\begingroup$ Related: (14645) $\endgroup$ – Mr.Wizard Mar 23 '20 at 20:43
6
$\begingroup$

But what if I wish to handle that error. So in this case, I want to return empty list {} if the part-does-not-exist error happens

One possibility might be

ClearAll[process];

process[lis_List, (n_Integer)?Positive] := Module[{},
       Quiet@Check[lis[[n]], {}, Part::partw]
]

Or just

process[lis_List, (n_Integer)?Positive] := Quiet@Check[lis[[n]], {}, Part::partw]

And now

list = {{1, 2}, {3, 4}};
process[list, 2]
 (*{3, 4}*)

and

process[list, 3]
(* {} *)

Quiet can be removed if you want to hear the beep and see the error message on console.

$\endgroup$
5
$\begingroup$

As with the essence of @Nasser's answer, I go with a simplified version for now.

Quiet[Check[{{1, 2}, {3, 4}}[[3]], {}], Part::partw]

This returns empty list if partw message happens.

$\endgroup$
4
$\begingroup$

Have you considered Query? Default behavior:

list = {{1, 2}, {3, 4}}

Query[3][list]
Missing["PartAbsent", 3]

Somewhat customized:

fn = Replace[Missing["PartAbsent", _] -> {}];

Query[3, fn][list]
{}

Or with care:

Unprotect[Missing];
Missing["PartAbsent", _] = {};
Protect[Missing];

Query[3][list]
{}

Caveat, Query can be slow:

$\endgroup$
2
$\begingroup$

Without using Quiet or Check you can use

SafePart[expr_, n_Integer?Positive, default_ : $Failed] := 
  If[Length[expr] >= n, Part[expr, n], default];
SafePart[expr_, parts : {__Integer?Positive}, default_ : $Failed] := 
 Fold[SafePart[#1, #2, default] &, expr, parts]

then you have

SafePart[{{{a, b}, {c}}}, {1, 2, 1}]
(* c *)

SafePart[{{{a, b}, {c}}}, 3, {}]
(* {} *)
$\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.