Php 在什么情况下,如果我们将排序后的数字作为键添加到哈希表中,我们可以期望哈希表是有序的?

Php 在什么情况下,如果我们将排序后的数字作为键添加到哈希表中,我们可以期望哈希表是有序的?,php,python,ruby,perl,hash,Php,Python,Ruby,Perl,Hash,在PHP中,当我们使用排序后的数字作为键将元素插入到新的哈希表中时,生成的哈希表也会被排序,这是真的吗 所以当我们拿到钥匙时,他们会被订购,$a[0]、$a[1]、$a[2]也会按照原来的顺序订购?(虽然可以肯定,键的顺序是那样的,但值不必如此) 在PHP中,我们可以指望这一点是真的吗?在Perl、Python或Ruby中没有这样的行为吗?Python有。其他语言也有对应的语言 但是,对于基本哈希类型(例如Python的dict),通常不能保证这种行为,因为它需要额外的簿记 PHP的数组是一片特

在PHP中,当我们使用排序后的数字作为键将元素插入到新的哈希表中时,生成的哈希表也会被排序,这是真的吗

所以当我们拿到钥匙时,他们会被订购,
$a[0]、$a[1]、$a[2]
也会按照原来的顺序订购?(虽然可以肯定,键的顺序是那样的,但值不必如此)

在PHP中,我们可以指望这一点是真的吗?在Perl、Python或Ruby中没有这样的行为吗?

Python有。其他语言也有对应的语言

但是,对于基本哈希类型(例如Python的
dict
),通常不能保证这种行为,因为它需要额外的簿记


PHP的数组是一片特殊的雪花;即使您使用的是PHP,也最好不要养成依赖于排序的基本哈希的习惯。

正如Amber所指出的,collections.OrderedDict是保证保留插入顺序的Python工具

尽管如此,我发现标题中提出的问题很有趣。Python的一个实现细节是整数的散列值就是值本身。由于常规的dict(通常是无序的)只是散列表,因此有时可以将已排序的数字添加到字典中,使其保持排序:

>>> from random import sample
>>> dict.fromkeys(range(5)).keys()
[0, 1, 2, 3, 4]
>>> dict.fromkeys(range(25)).keys()
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
>>> dict.fromkeys(range(0,25,2)).keys()
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24]
>>> dict.fromkeys(sorted(sample(range(50), 40))).keys()
[0, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 15, 16, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 31, 32, 33, 34, 35, 36, 38, 39, 40, 41, 42, 43, 44, 45, 47, 49]
这个结果是脆弱的,不是一个保证的行为。它依赖于以下属性:

  • 键的位置根据其哈希值与dict大小(从8开始)的模值确定
  • 整数的散列值就是整数本身
  • 当哈希表已满三分之二时,它的大小将向上调整四倍(当它开始翻倍时最高可达50000),并重新插入现有的键/值对
问:在什么情况下,如果我们将排序后的数字作为键添加到哈希表中, 我们能指望订购散列吗

答:当且仅当按字典大小取模n时,这些值保持排序,并且当添加元素时创建的每个较小字典的条件也成立时,排序后的数字键在常规dict中保持排序:

  • 取模8时,前五个元素(8*2//3)必须排序
  • 取模32时,必须对前21个元素(32*2//3)进行排序
  • 取模块128时,必须对前85个元素(128*2//3)进行排序
  • 等等
代码:

def will_remain_sorted(seq):
    i, n = 0, 8
    while i < len(seq):
        i = n * 2 // 3
        if not sorted(seq[:i], key=lambda x: x%n) == seq[:i]:
            return False
        n *= 4 if n < 50000 else 2
    return True
def将保持排序(顺序):
i、 n=0,8
而我
Perl中的行为记录在:

散列的键以明显的随机顺序返回。在未来的Perl版本中,实际的随机顺序可能会发生更改,但可以保证其顺序与值或每个函数生成的顺序相同(假定哈希未被修改)。由于Perl 5.8.1,出于安全原因,即使在不同的Perl运行之间,顺序也可能不同(请参阅)

您可以使用:

此Perl模块实现Perl哈希,保留添加哈希元素的顺序。当与
IxHash
中现有键对应的值发生更改时,顺序不受影响。元素也可以设置为任意提供的顺序。熟悉的Perl数组操作也可以在
IxHash
上执行


我相信(标准)Ruby 2哈希也是基于插入排序的。Java有LinkedHashMap。我认为Perl无法对哈希进行排序,如果我错了,请纠正我。当然,您可以对每个$key进行
排序(对key%coins进行排序)
,但实际上这是一个涉及对数组进行排序的技巧。纯散列不按定义排序,因为它们基于没有顺序的散列函数。@m0skit0不,你错了。Perl有各种各样的排序哈希,但它们都需要更多的簿记,至少在内部是这样,因此效率较低。不过,只要特别就足够了。@Lattyware的确,雪花很漂亮;-)在“罚款手册”规定的情况下有效。如果没有特别说明,那么就不要依赖它。你为什么想要或需要依赖这种行为?@pst什么是“优秀手册”--你指的是。。。PHP手册打开?@Karl因为如果我已经有了一些排序的数字。。。假设它们在一个链表中,或者在PHP中作为数组中的“值”。。。我需要使用一种算法将这些数字作为“键”放入一个哈希表中,我需要你提供更详细的信息。还有很多。首先,通过以这种方式排列数据来描述要解决的问题。是IxHash的更快的替代方案。