所有..Values
个函数都有未记录的选项Sort
:
In[1]:= Options /@ {OwnValues, DownValues, UpValues, SubValues,
DefaultValues, FormatValues, NValues}
Out[1]= {{Sort -> True}, {Sort -> True}, {Sort -> True}, {Sort ->
True}, {Sort -> True}, {Sort -> True}, {Sort -> True}}
这个选项的用途和用途可能有用吗?
答案 0 :(得分:8)
输入函数的定义时,请按特定顺序输入它们。如果您的定义不包含模式,它们将在内部存储在哈希表中。当您请求它们时,它们将默认排序:
In[11]:=
Clear[g];
g[5]=1;
g[4]=2;
g[3]=3;
In[15]:= DownValues[g]
Out[15]= {HoldPattern[g[3]]:>3,HoldPattern[g[4]]:>2,HoldPattern[g[5]]:>1}
但是,通常您可能希望查看分配值的原始顺序。方法如下:
In[16]:= DownValues[g,Sort->False]
Out[16]= {HoldPattern[g[5]]:>1,HoldPattern[g[4]]:>2,HoldPattern[g[3]]:>3}
您可能想要使用它的一个实例的示例是,当您需要实现缓存时(我可以找到基于此选项的尝试here)。但是,对于大量定义,可能无法保证定义将遵循原始顺序,因为内部散列表可能会被扩展和重新散列多次。通常,哈希表实现不保证键值对的存储顺序。因此,通过设置Sort->False
您所获得的是...Values
在返回给您之前不会被Mathematica排序,因此您可以按照Mathematica目前存储它们的顺序获得它们。
另一种情况,当您想要使用DownValues
构建类似字典的结构时 - 在这种情况下,Sort->False
的密钥提取会更快,因为没有排序必须执行密钥集(大密钥集的事项):
In[31]:=
Clear[gg];
(gg[#]:=200000-#)&/@Range[200000];
In[33]:= DownValues[gg][[All,1,1,1]]//Short//Timing
Out[33]= {4.867,{1,2,3,<<199994>>,199998,199999,200000}}
In[34]:= DownValues[gg,Sort->False][[All,1,1,1]]//Short//Timing
Out[34]= {2.103,{95090,102286,<<199996>>,38082,26686}}
您可以找到此类用途的示例,例如here
据我所知,Sort
选项仅影响非基于模式的DownValues
(以及其他...Values
),因为基于模式的DownValues
Mathematica无论如何都试图按照它们的一般性顺序对它们进行重新排序,因为它理解这一点。 OTOH,对于基于模式的DownValues
,您可以进行手动规则重新排序,Mathematica将保留您的更改,而对于没有模式的定义,尝试在最初给出后手动重新排序定义似乎对它们没有影响(也许,再次因为它们在内部进行哈希处理,而哈希表通常不关心顺序)。