什么"排序"选项...值吗?

Ale*_*kov 5 wolfram-mathematica

所有..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}}
Run Code Online (Sandbox Code Playgroud)

这个选项的用途和用途可能有用吗?

Leo*_*rin 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}
Run Code Online (Sandbox Code Playgroud)

但是,通常您可能希望查看分配值的原始顺序.方法如下:

In[16]:= DownValues[g,Sort->False]
Out[16]= {HoldPattern[g[5]]:>1,HoldPattern[g[4]]:>2,HoldPattern[g[3]]:>3}
Run Code Online (Sandbox Code Playgroud)

您可能想要使用它的一个实例的示例是当您需要实现缓存时(我可以在此处找到基于此选项的尝试).但是,对于大量定义,可能无法保证定义将遵循原始顺序,因为内部散列表可能会被扩展和重新散列多次.通常,哈希表实现不保证键值对的存储顺序.所以,你通过设置实现的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}}
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到此类用途的示例.

据我所知,该Sort选项仅影响非基于模式DownValues(和其他...Values),因为对于基于模式的DownValuesMathematica无论如何都试图按照它们的一般性顺序对它们进行重新排序,因为它理解这一点.OTOH,对于基于模式的DownValues,您可以进行手动规则重新排序,Mathematica将保留您的更改,而对于没有模式的定义,尝试在最初给出后手动重新排序定义似乎对它们没有影响(可能,再次因为它们在内部进行哈希处理,哈希表通常不关心顺序).

  • @acl典型的散列表具有一定的容量 - 它可以有效地散列的许多元素,而不会使碰撞概率变得太高.当我们不断添加定义时,哈希表可能会在某些时候执行动态调整大小,从而增加其容量.根据实现,它可能需要也可能不需要重新哈希现有条目.这些内容在这里得到了很好的解释:http://en.wikipedia.org/wiki/Hash_table.大多数哈希表都不维护键的顺序,但是有一些(例如Java中的`LinkedHashMap`). (2认同)