【问题标题】:Can I reliably use the indexes of list generated by python dictionary key method?我可以可靠地使用python字典键方法生成的列表索引吗?
【发布时间】:2014-05-08 01:53:22
【问题描述】:

假设我有这本字典:

mydict = {'1': ['a', 'b', 'c'], 
          '2': ['d', 'e', 'f'], 
          '3': ['g', 'h', 'i'], 
          '4': ['j', 'k', 'l'], 
          '5': ['m', 'n', 'o']}

根据 Python 文档,

字典对象的keys()方法返回一个包含所有 字典中使用的键,按任意顺序

当我调用mydict.keys() 方法时,它会给我一个mydict 中的键列表,没有任何特定顺序,如下所示:

['1', '3', '2', '5', '4']

我的问题是.keys() 方法生成的键列表(上图)是否每次调用时都具有相同的顺序?我已经尝试过使用这样的 for 循环:

for i in range(100):
    print mydict.keys()

在我看来,结果列表始终具有相同的顺序。但我只是想确认没有隐藏的情况会改变输出列表的顺序。

换句话说,如果我使用 mydict.keys()[0] ,我每次都会得到相同的物品吗?

【问题讨论】:

  • 不会赌上我的性命...
  • 只要不向字典中添加元素我认为应该没问题。但我让 Python 专家发言。
  • @FelixKling,我认为它也可能因版本而异
  • 我敢打赌它是按 hashmap 顺序排列的,所以如果你在完全相同的解释器上运行时以完全相同的方式构造字典,它很可能是相同的。尝试添加几千个项目并删除它们,我敢打赌订单会改变。
  • @sshashank124:可能。但无论如何,如果问题归结为“如果连续调用两次,.keys() 是否返回相同的列表”,我会说是的。并不是字典的元素以不确定的方式存储,我认为阅读字典也不会影响它的内部存储结构。改变字典当然可以改变内部存储元素的“顺序”。

标签: python python-2.7 dictionary key


【解决方案1】:

在使用 dict 时,您永远不应该依赖排序。即使您对其进行了 10 亿次测试并且它看起来是同质的,但规范中没有任何内容表明它是同质的,因此可能会有一些隐藏的代码说“每个满月开始在偶数日,更改顺序”。

如果您想依赖排序,请使用OrderedDict from collections

【讨论】:

  • +1 表示OrderedDict。如果规范说“以任意顺序返回字典中使用的所有键的列表”,那么您编写代码以尊重这一点。
【解决方案2】:

我的问题是 .keys() 方法生成的密钥列表(上图) 每次调用的顺序都是一样的吗?

如果没有对字典进行干预修改,那么顺序将是相同的。

引用documentation:

如果items()keys()values()iteritems()iterkeys()itervalues() 被调用,没有对 字典,列表将直接对应。这允许 使用zip(): pairs = zip(d.values(), d.keys()) 创建(value, key) 对。 iterkeys()itervalues() 方法:pairs = zip(d.itervalues(), d.iterkeys()) 为对提供相同的值。创建相同列表的另一种方法 是pairs = [(v, k) for (k, v) in d.iteritems()]

【讨论】:

    【解决方案3】:

    简短的回答是否定的,您不能依赖订单。 原因是键被散列并相应地放置在表中。每当字典满 2/3 时(我认为这是数字),表格的大小就会向上调整,以避免太多的冲突并保持 O(1) 访问时间,并向下调整(我认为当它是1/3 满),用于管理内存利用率。

    因为是哈希表,字典的构建顺序会影响键的排序。 哈希函数在未来的版本中可能会改变...

    如果您需要以可靠的顺序使用密钥,您可以查看 collections OrderedDict,这可能就是您要找的。 [编辑:我刚刚注意到您使用的是 python 2.7,OrderedDict 仅在 Python 3.+ 中可用]

    【讨论】:

      猜你喜欢
      • 2017-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-06
      • 1970-01-01
      • 1970-01-01
      • 2021-10-08
      • 2018-07-27
      相关资源
      最近更新 更多