Mathematica's puzzling interpretation of #^2 &

2019-07-04 01:15发布

问题:

I'm puzzled by Mathematica's responses to the following:

ClearAll[n]
#^2 & /@ Range[n]
#^2 & /@ Range[n] // StandardForm

It seems that even Mathematica (8.0) doesn't believe what it has just said:

#^2 & /@ Range[5]
Range[5^2]

Any thoughts about what is happening?

Edit:

The original context for this question was the following. I had written

PrimeOmega[Range[n]] - PrimeNu[Range[n]]

and since n was going to be very large (2^50), I thought I might save time by rewriting it as:

 PrimeOmega[#] - PrimeNu[#] &/@Range[n]

Thinking back, that probably wasn't such a good idea. (I could have used Module to 'compute' the Range only once.)

回答1:

Since n is undefined, Range[n] evaluated to itself. Therefore, Map acts on it as on any other symbolic head, mapping your function on its elements - here it is just n

In[11]:= #^2 & /@ someHead[n]
Out[11]= someHead[n^2]

EDIT

Addressing the question in your edit - for numeric n, Range evaluates to a list all right, and you get the expected result (which is, Range[5]^2. It is all about the order of evaluation. To get Range[5^2], you could have used #^2&/@Unevaluated[Range[5]], in which case everything happens just like for symbolic n above) . In fact, Range issues an error message on non-numeric input. Also, it is tangential to the question, but functions like #^2& are Listable, and you don't have to map them.



回答2:

Slightly off topic, but you can improve the speed by redefining in terms of FactorInteger, which then is only called once per input.

f1[n_] := PrimeOmega[Range[n]] - PrimeNu[Range[n]]
f2[n_] := With[{fax=FactorInteger[#]}, Total[fax[[All,2]]]-Length[fax]]& /@ Range[n]

Example:

In[27]:= Timing[pdiff1 = f1[2^20];]
Out[27]= {37.730264, Null}

In[28]:= Timing[pdiff2 = f2[2^20];]
Out[28]= {9.364576, Null}

In[29]:= pdiff1===pdiff2
Out[29]= True

Daniel Lichtblau