4
$\begingroup$

Ok. I'm obviously not understanding something about pattern matching.

I have a list called t like the following:

t = {{3.2,5.9,Indeterminate},{4.5,-3 - 100 (1 - 2/(Underflow[] + 1)) + 200 (1 - Underflow[]),7.9},{1.2,9.1,2.3}}

Where I would like to use ReplaceAll[] to convert all non-real values to 0.0, like so:

{{3.2,5.9,0.0},{4.5,0.0,7.9},{1.2,9.1,2.3}}

How could I do this with ReplaceAll[] and pattern matching?

I have tried:

t /. r_ /; Head[r] != List | Real -> 0.0

But that does nothing to the list. I am trying to wrap my head around pattern matching, but I'm not quite there yet, and any help would be greatly appreciated.

Thanks!

P.S.- I would really like to understand this in context of pattern matching, but other more efficient ways of doing this are also appreciated!

$\endgroup$

5 Answers 5

7
$\begingroup$

You had two issues.

  1. You can't use Unequal ("!=") with Alternatives ("|").
  2. Even if you correct your pattern, the pattern would match the whole expression.

Using Replace with a level spec and a corrected pattern:

t = {{3.2,5.9,Indeterminate},{4.5,-3-100 (1-2/(Underflow[]+1))+200 (1-Underflow[]),7.9},{1.2,9.1,2.3}};

Replace[
    t,
    r_ /; !MatchQ[Head[r], List | Real] -> 0.0,
    {2}
]

{{3.2, 5.9, 0.}, {4.5, 0., 7.9}, {1.2, 9.1, 2.3}}

Another possibility:

Replace[
    t,
    Except[_?NumberQ] -> 0.,
    {2}
]

{{3.2, 5.9, 0.}, {4.5, 0., 7.9}, {1.2, 9.1, 2.3}}

$\endgroup$
1
  • $\begingroup$ Great, thanks! That helps me to understand it a lot better $\endgroup$
    – Jmeeks29ig
    Commented Sep 20, 2018 at 1:00
2
$\begingroup$

I prepended 11, 1/3 and 4 + 3 I to the first sublist

list =
  {{11, 1/3, 4 + 3 I, 3.2, 5.9, Indeterminate},
   {4.5, -3 - 100 (1 - 2/(Underflow[] + 1)) + 200 (1 - Underflow[]), 7.9},
   {1.2, 9.1, 2.3}};

1.

RealValuedNumberQ (new in 13.3) gives, in my opinion, the best solution (according to the title of the question)

Replace[list, Except[_?RealValuedNumberQ] -> 0., {2}]

{{11, 1/3, 0., 3.2, 5.9, 0.}, {4.5, 0., 7.9}, {1.2, 9.1, 2.3}}

2.

This replaces 11 and 1/3 (which are real numbers)

Replace[list, x_ /; Head[x] =!= Real -> 0., {2}]

{{0., 0., 0., 3.2, 5.9, 0.}, {4.5, 0., 7.9}, {1.2, 9.1, 2.3}}

3.

This doesn't replace 4 + 3 I

Replace[list, Except[_?NumberQ] -> 0., {2}]

{{11, 1/3, 4 + 3 I, 3.2, 5.9, 0.}, {4.5, 0., 7.9}, {1.2, 9.1, 2.3}}

$\endgroup$
2
$\begingroup$
list = {{3.2, 5.9, Indeterminate}, {4.5, -3 - 100 (1 - 2/(Underflow[] + 1)) + 
         200 (1 - Underflow[]), 7.9}, {1.2, 9.1, 2.3}};

Using Cases and If:

Cases[#, x_ :> If[MatchQ[x, _?NumberQ], x, 0.]] & /@ list

(*{{3.2, 5.9, 0.}, {4.5, 0., 7.9}, {1.2, 9.1, 2.3}}*)
$\endgroup$
1
$\begingroup$
list = 
 {{3.2, 5.9, Indeterminate}, 
  {4.5, -3 - 100 (1 - 2/(Underflow[] + 1)) + 200 (1 - Underflow[]), 7.9}, 
  {1.2, 9.1, 2.3}};

Using ReplaceAt (new in 13.1)

ReplaceAt[list, Except[_Real] :> 0.0, {All, All}]

{{3.2, 5.9, 0.}, {4.5, 0., 7.9}, {1.2, 9.1, 2.3}}

$\endgroup$
1
$\begingroup$

With some extra levels added for testing:

list = {{3.2, 5.9, 
    Indeterminate}, {{{{4.5, -3 - 100 (1 - 2/(Underflow[] + 1)) + 
        200 (1 - Underflow[]), 7.9}}, {1.2, 9.1, 2.3}}}};

list /. a_?VectorQ :> SequenceReplace[a, {Except[_Real]} :> 0.0]

{{3.2, 5.9, 0.}, {{{{4.5, 0., 7.9}}, {1.2, 9.1, 2.3}}}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.