如何访问字典或散列中的第n项?

时间:2011-01-08 14:08:39

标签: language-agnostic dictionary hashmap

我有一个键和值的字典,例如:

{
    fred: 1,
    dave: 2,
    lily: 3
}

如何获取字典中的第二个元素 - 在这种情况下为{dave:2}


背景:我已经在SO上以这种或那种形式多次询问过这个问题, 所以我想我会写一个Q& A页面作为社区维基,人们可以 提到并且可能有希望成为这个问题的规范答案。

这个Q& A适用于词典,因为它们以多种不同的方式实现 语言。不同的语言使用不同的名称来指代是什么 基本上相同的数据结构 - 例如它们被称为哈希 Perl,Python中的词典。在Objective-C中,他们是实例 NSDictionaryNSMutableDictionary个类。

2 个答案:

答案 0 :(得分:13)

简而言之,你不能 - 因为字典无序 键/值对的集合。填充字典的顺序 没有保留在内存中。这是Python中的一个简单示例:

>>> dict = { 'a': 1, 'b': 2, 'c': 3 }
>>> dict # show the value of dict in memory
{'a': 1, 'c': 3, 'b': 2}

正如您所看到的,虽然字典是使用键初始化的 命令a,b,c,打印字典的值显示它们 订购了a,c,b。即使这种排序也不会保留在内存中; 当您向字典中添加更多键/值对时,将其中的顺序添加到字典中 上面的表达将继续改变。

为什么会这样?

字典针对快速存储和检索值进行了优化 基于唯一键。实施方式因语言而异 接下来,但通常它的工作原理如下:

  • 字典由N个元素的标准数组支持
  • 在存储键/值对时,键是通过一个函数来完成的 将其转换为整数(“散列函数” - 因此得名) Perl中此数据结构的“哈希”)。一个简单的散列函数 对于ASCII字符串键可能是要添加每个的ASCII值 字符。 (注意:这不是良好的哈希算法 - 只是一个 一个简单的例子!)
  • 然后将整数除以数组的大小和余数 该分区用作数组的索引
  • 如果已经填充了该索引处的数组元素 使用各种技术中的一种来解决冲突(例如, 数组元素的内容本身就是一个数组 新值及其未散列的密钥将被附加)
  • 检索的工作方式与存储方式相同:取钥匙,使用它 派生一个数组索引,然后检索与之关联的值 键
  • 可以在字典增长时调整后备数组的大小:调整大小时 在数组中,字典中的每个元素都有其哈希值除以 新的数组大小,产生一个新的余数,即一个新的位置 在后备阵列中。

答案 1 :(得分:1)

我是新手,所以无法添加评论.....但这实际上是对Simon的上述答案的评论。

有用的问题&好的答案,西蒙。你可以在答案中添加另一个部分,说,因此,这个问题唯一有意义的方法是,如果我们采取类似以下示例的方法

  • sort(dict)然后获取这个新排序字典的第n项。这将每次生成完全相同的第n个字典,即使底层数组增长。
  • 枚举(dict)并获取字典中的第n个键