Group Abstract Group Abstract

Message Boards Message Boards

0
|
167 Views
|
4 Replies
|
5 Total Likes
View groups...
Share
Share this post:

Negation of IntegerQ in replacement condition causes error?

Posted 3 days ago

Replace All elements in a list under a condition using IntegerQ completes

{1, 2, 1/3, 3, 4, 1/5} /. x_ /; IntegerQ[x] -> w

{w, w, 1/3, w, w, 1/5}

However changing the condition to negating IntegerQ

{1, 2, 1/3, 3, 4, 1/5} /. x_ /; ! IntegerQ[x] -> w

w

vice the expected result

{1, 2, w, 3, 4, w}

Why?

The result is the same when

Element[x, Integers] -> w 

Is used rather than IntegerQ

POSTED BY: Dennis Caro
4 Replies
Posted 1 day ago

PatternTest (what the ? is shorthand for) requires a function. That function will be applied to the arguments supplied by whatever pattern matching situation is occurring. Condition (what the /; is shorthand for) requires an expression that (presumably) evaluates to True or False when evaluated with replacements being supplied by the pattern matching. What I gave previously was actually a bit over-specified. I should have suggested this:

Replace[{1, 2, 1/3, 3, 4, 1/5}, _?(Not@*IntegerQ) -> w, 1]

Notice I removed the x as the name of the pattern, because it's never referred to in the rest of the pattern. Another way to do it if you don't like Composition would be:

Replace[{1, 2, 1/3, 3, 4, 1/5}, _?(Not[IntegerQ[#]] &) -> w, 1]

That also works if you don't like spelling out Not:

Replace[{1, 2, 1/3, 3, 4, 1/5}, _?(! IntegerQ[#] &) -> w, 1]

Regardless, you need a function, i.e. a thing that can be applied to arguments.

If you want to use Condition instead of PatternTest, then you don't use a "pure" function but an expression:

Replace[{1, 2, 1/3, 3, 4, 1/5}, x_ /; Not[IntegerQ[x]] -> w, 1]

The same explanation applies to Gianluca's suggestion:

(* Condition *)
{1, 2, 1/3, 3, 4, 1/5} /. x_ /; NumericQ[x] && ! IntegerQ[x] -> w

(* PatternTest *)
{1, 2, 1/3, 3, 4, 1/5} /. _?(NumericQ[#] && ! IntegerQ[#] &) -> w
POSTED BY: Eric Rimbey
Posted 2 days ago

Mr. Rimbey -
Thank you for your detailed explanation; and also for an example of how to get the desired result.

I did find that function composition seems to be necessary for the negation, i.e.

In[884]:= Replace[{1, 2, 1/3, 3, 4, 1/5}, x_?(Not@*IntegerQ) -> w, 1]

Out[884]= {1, 2, w, 3, 4, w}

while

In[766]:= Replace[{1, 2, 1/3, 3, 4, 1/5}, x_?(! IntegerQ) -> w, 1]

Out[766]= {1, 2, 1/3, 3, 4, 1/5}

fails in a different way :-)

Mr. Gorni -
Thank you as well.

In[885]:= {1, 2, 1/3, 3, 4, 1/5} /.  x_ /; NumericQ[x] && ! IntegerQ[x] -> w

Out[885]= {1, 2, w, 3, 4, w}

You show a way to calm Mathematica's dislike of negation not bound in a direct function composition That dislike for a "naked" negation seems to still exist

In[886]:= {1, 2, 1/3, 3, 4, 1/5} /. x_ /; ! IntegerQ[x] -> w

Out[886]= w

Again, I thank both of you. This is a wonderful community.
-Dennis Caro

POSTED BY: Dennis Caro

Another way:

{1, 2, 1/3, 3, 4, 1/5} /. x_ /; NumericQ[x] && ! IntegerQ[x] -> w
POSTED BY: Gianluca Gorni
Posted 3 days ago

ReplaceAll looks at all parts of an expression. That includes the head of the overall expression as well as head of subexpressions and it also includes the overall expression itself. So, when you used IntegerQ, IntegerQ[{...}] was false, so no replacement was made, IntegerQ[List] was false, so no replacement was made, then we moved to subexpressions, and IntegerQ[1] was true, and so a replacement was made, etc etc. When you used Not[IntegerQ[]], Not[IntegerQ[{...}]] was true so a replacement was made that happened to replace the entire expression.

Probably the easiest fix is to use Replace instead:

Replace[{1, 2, 1/3, 3, 4, 1/5}, x_?(Not@*IntegerQ) -> w, 1]
(* {1, 2, w, 3, 4, w} *)
POSTED BY: Eric Rimbey
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard