Wolfram mathematica 什么;排序“;价值观的选择是什么?

Wolfram mathematica 什么;排序“;价值观的选择是什么?,wolfram-mathematica,Wolfram Mathematica,所有.Values函数都有未记录的选项排序: In[1]:= Options /@ {OwnValues, DownValues, UpValues, SubValues, DefaultValues, FormatValues, NValues} Out[1]= {{Sort -> True}, {Sort -> True}, {Sort -> True}, {Sort -> True}, {Sort -> True}, {Sort -> T

所有
.Values
函数都有未记录的选项
排序

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}}

此选项的作用和用途是什么?

输入函数定义时,请按特定顺序输入定义。如果您的定义不包含模式,它们将存储在哈希表中。当您请求它们时,默认情况下它们将被排序:

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}
您可能希望使用它的一个实例的示例是,当您需要实现缓存时(可以找到我基于此选项尝试实现缓存的结果)。但是,对于大量的定义,可能无法保证这些定义将按照原始顺序进行,因为内部哈希表可能会被扩展和重新哈希多次。通常,哈希表实现不能保证键值对的存储顺序。因此,通过设置
Sort->False
可以实现的是,
…值在返回给您之前不会按Mathematica进行排序,因此您可以按照Mathematica当前存储它们的顺序获取它们

另一种情况是,您可能希望使用
DownValues
构建类似字典的结构-在这种情况下,使用
Sort->False
进行键提取要快得多,因为不必对键集进行排序(对于大型键集很重要):

[31]中的
:=
清除[gg];
(gg[#]:=200000-#)和/范围[200000];
在[33]:=DownValues[gg][[All,1,1,1]]//Short//计时
Out[33]={4.867,{1,2,3,1999981999900000}
在[34]:=DownValues[gg,Sort->False][[All,1,1,1]//Short//计时
Out[34]={2.103,{95090102286,,3808226686}
你可以找到这种用法的一个例子,例如


据我所知,
排序
选项只会影响非基于模式的
下行值
(以及其他
…值
),因为对于基于模式的
下行值
Mathematica无论如何都会尝试按照它们的一般性顺序对它们重新排序,正如它所理解的那样。OTOH,对于基于模式的
DownValues
,您可以进行手动规则重新排序,Mathematica将保留您的更改,而对于没有模式的定义,在最初给出定义后尝试手动重新排序似乎对其没有影响(可能也是因为它们是内部散列的,而散列表通常不关心顺序)。

您可以在“…因为内部散列表可能会被扩展并重新散列几次”上展开一点吗?@acl一个典型的哈希表有一定的容量——它可以有效地哈希许多元素,而不会使冲突概率变得太高。当我们不断添加定义时,在某个时候,哈希表可能会执行动态调整大小,从而增加其容量。根据实现情况,它可能需要或可能不需要重新哈希现有条目这里很好地解释了这些事情:。大多数哈希表不维护键的顺序,但也有一些(例如Java中的
LinkedHashMap
)我想我更多的是问你是否观察到mma这样做,如果是的话,是怎么做的。@acl好的,关于键的顺序,我的第二个例子表明键没有特定的顺序。我的实验表明,只有非常小的键集,大约15个元素或更少,才保持原始顺序。在
SystemOptions
控制这个,但是我没有找到它。至于动态增长,看看这些系统选项:
SystemOptions[“HashTableOptions”]
(我有
{“HashTableOptions”->{“GrowLoadFactor”->2.,“ShrinkLoadFactor”->0.5}
)。加载因子基本上是每个bucket的平均条目数(引用的维基百科文章提供了更多信息)。@Leonid:一如既往,让你来回答这个问题是有回报的!谢谢你有趣的阅读。+1
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}}