当我将Python 3.8.0列表转换为集合时,结果集的排序*以一种很简单的方式高度结构化。如何从伪随机列表中提取此结构?
作为实验的一部分,我正在生成一个随机集合。我很惊讶地看到绘制该集合突然显示出该集合中意外的线性结构。因此,有两件事让我感到困惑-为什么转换为一组结果会导致排序*最终突出了这种结构;在较小程度上,为什么伪随机集完全具有这种“隐藏”结构?
编码:
X = [randrange(250) for i in range(30)]
print(X)
print(set(X))
例如输出
[238, 202, 245, 94, 111, 106, 148, 164, 154, 113, 128, 10, 196, 141, 69, 38, 106, 8, 40, 53, 160, 87, 85, 13, 38, 147, 204, 50, 162, 91]
{128, 8, 10, 141, 13, 147, 148, 154, 160, 162, 164, 38, 40, 50, 53, 196, 69, 202, 204, 85, 87, 91, 94, 106, 238, 111, 113, 245}
正如预期的那样,以上列表的图**看起来相当随机:
而绘制集合(按其在输出中的排序)则显示出集合中存在的结构:
此行为在我的机器上(下面的更多示例)与上面的代码中使用的值250和30保持100%一致(我使用的示例不是精心挑选的-这只是我运行的最后一个)。调整这些值有时会导致结构略有不同(例如,三个算术级数的子集***而不是两个)。
在其他人的机器上可以复制吗?当然,这种结构的存在似乎表明不是那么好的伪随机数生成,但是这并不能解释在某种意义上如何转换为集合。据我所知,并没有正式的保证(从列表中转换时)集合的顺序是确定性的(即使是顺序排列,在后台也不会进行复杂的排序)。那怎么回事?
(*):我知道集合是无序集合,但我的意思是“有序集合”,即在调用print语句时,集合以某种顺序输出,从而始终突出显示底层集合结构。
(**):这些地块来自Wolfram Alpha。下面是两个示例:
(***):将随机数范围从250更改为500时的两个图:




