【问题标题】:python 3.6 collections document mistake found?发现python 3.6 collections 文件错误?
【发布时间】:2017-12-25 03:29:42
【问题描述】:

您好,我在 python 3.6 中发现:

cnt = collections.Counter(['red', 'blue', 'red', 'green', 'blue', 'blue'])
print(cnt)  # >>> Counter({'blue': 3, 'red': 2, 'green': 1})

在文档中,它说'elements() 返回一个遍历元素的迭代器,每个元素重复其计数的次数。元素以任意顺序返回。'

但是:

print(list(cnt.elements()))  

永远给我:

['red', 'red', 'blue', 'blue', 'blue', 'green']

我不认为它是任意顺序了,它取决于原始数据出现的顺序:

cnt = collections.Counter(['red', 'green', 'red', 'blue', 'blue', 'blue'])
print(list(cnt.elements())) 
# >>> ['red', 'red', 'green', 'blue', 'blue', 'blue']

如果我在列表中切换“蓝色”和“绿色”,我将在cnt.elements() 中的“蓝色”之前得到“绿色”

我的发现是正确的还是我的做法不对?

【问题讨论】:

  • 来自 Raymond Hettinger‏ “raymondh #python 新闻:???? gvanrossum 刚刚宣布字典现在保证保留插入顺序。这是漫长旅程的结束。” 2017 年 12 月 15 日上午 8:40。twitter.com/raymondh/status/941709626545864704
  • 来自 Guido van Rossum "gvanrossum 回复 yaroslavvb raymondh ogrisel 这个线程中的第一个好问题。集合保持无序。(为什么?使用模式不同。另外,不同的实现。)"。晚上 10:05 - 2017 年 12 月 15 日。twitter.com/raymondh/status/941709626545864704

标签: python-3.x collections


【解决方案1】:

这是由于a change in the implementation of dict in Python 3.6:

dict 类型现在使用基于 Raymond Hettinger 提议的“紧凑”表示,该提议首先由 PyPy 实现。与 Python 3.5 相比,新 dict() 的内存使用量减少了 20% 到 25%。

这个新实现的顺序保留方面被认为是一个实现细节,不应依赖(这可能会在未来发生变化,但希望在更改之前在几个版本中使用该语言的这个新 dict 实现语言规范为所有当前和未来的 Python 实现强制要求保持顺序的语义;这也有助于保持与随机迭代顺序仍然有效的旧版本语言的向后兼容性,例如 Python 3.5)。

【讨论】:

  • 所以基本上是在上一个版本(3.5到3.6)的更新过程中发生了变化。我应该向谁报告,提醒更新 3.6 中的文档吗?
  • @Code_Control_jxie0755:我认为他们不会认为这是值得修复的文档的问题。即使抛开对“任意”含义的潜在胡扯,上面的引文也明确指出“不应该依赖订单保持方面......”所以他们不会将文档更改为“插入顺序”被保留,”因为这会隐含地告诉人们依赖它。
  • @Code_Control_jxie0755 Counter 文档是正确且一致的 - 容器的 elements() 方法本身不保证任何形式的排序 - 只是键重复正确的次数并且连续 - 这是唯一的它需要履行的合同。在最常见的用例中,对于特定版本的 Python 及其默认基本存储的特定实现,它可以作为副作用的一部分,这一事实既不存在也不存在。
【解决方案2】:

Python 3.6 dict 现在是 ordered

由于collections.Counter是内置类型dict的直接subclass,所以也按顺序存储。


正如 python 3.6 update note 所说,不应该依赖 dict 的顺序,因为它只是一个实现细节;您不应该依赖 .elements() 返回有序元素这一事实。

但从 Python 3.7 开始,您可以确定 dict 将始终 keep insertion order

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    • 2018-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多