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$
  • 2
    $\begingroup$ Have you seen Indexed[]? $\endgroup$ – J. M.'s discontentment Mar 21 at 10:29
  • 1
    $\begingroup$ Indexed[list,3] would also give error. $\endgroup$ – liang Mar 21 at 11:19
  • $\begingroup$ +1 for it's a good mentioning. $\endgroup$ – liang Mar 21 at 11:42
  • $\begingroup$ Related: (14645) $\endgroup$ – Mr.Wizard Mar 23 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.

| improve this answer | |
$\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.

| improve this answer | |
$\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:

| improve this answer | |
$\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, {}]
(* {} *)
| improve this answer | |
$\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.