【问题标题】:OrderedDict in python 3 - how to get the keys in order?python 3中的OrderedDict - 如何按顺序获取键?
【发布时间】:2017-05-24 00:25:16
【问题描述】:

在 python 2 中,当使用 OrderedDict 时,我可以通过简单地使用返回列表的 keys 方法按插入顺序获取键。然而在 python 3 中:

rows = OrderedDict()
rows[0]=[1,2,3]
rows[1]=[1,2,3]
image = [rows[k] for k in rows.keys()[:2]]

我明白了:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: 'odict_keys' object is not subscriptable

我当然可以按照here 的建议做list(rows)[:2] - 但这能保证我按顺序拿到钥匙吗?这是正确的方法吗?

更新:python 2代码会更好:

image = [v for v in rows.values()[:2]]

当然在 python 3 上仍然会出现同样的错误

【问题讨论】:

  • 是的,使用list(rows) 是按顺序获取密钥的正确方法,因为它使用保证有序的__iter____next__。如果您只需要前 2 个键,您可能需要考虑类似 itertools.islice(rows, 2) 而不是 list(rows)[:2] ...
  • 谢谢@mgilson - 不知道什么会更快 - 复制一个小列表或使用 itertools 模块 - 也许尝试一个答案? :)

标签: python python-3.x ordereddictionary


【解决方案1】:

@mglison 是对的。因为OrderedDict遵循迭代器协议,所以保证yield的key按照正确的顺序到list()

然而,就像@mglison 也提到的那样,itertools.islice() 会比简单地使用list 和下标更好、更有效。在使用timeit 模块对这两种方法进行多次计时后,itertools 方法的速度大约快了 2 倍。以下是确切的数字:

在获得运行list(itertools.islice(rows, 2))list(rows.keys())[:2] 的平均时间后(注意我将islice() 的结果转换为一个列表)多次,看来使用后一种方法实际上稍微快一点:

---------------------------------------------------------------
|  list(itertools.islice(rows, 2))   |    1.5023668839901838  |      
---------------------------------------------------------------
|  list(rows.keys())[:2]             |    1.495460570215706   |      
---------------------------------------------------------------

但是,这两个数字的差异是如此之小,我真的不会在你使用哪种方法时有太大的区别。只需选择最适合您的具体案例的可读性和可理解性的方法即可。

【讨论】:

  • 如果这正是您所做的,我认为这不是一个公平的比较:itertools.islice(rows, 2) 本身并没有列出清单。您需要将其与 list(itertools.islice(rows, 2)) 进行比较,我怀疑这两种方法在那时看起来会更接近。
  • @DSM 啊,你的好东西。我不知道我的大脑在哪里。我将重新计算代码 sn-ps 并更新我的答案。
  • zzzz 请添加 timeit 代码 zzzz :) - @DSM - 但是我有兴趣按顺序迭代键,以便进行公平比较
  • 谢谢 - 我要睡觉了 - 顺便说一句,现在我仔细看我可能需要itertools.islice(rows.values(), 2)
  • 我认为itertools能否胜出很大程度上取决于字典的大小。如果 dict 真的很大,我怀疑 itertools 会更快。如果 dict 很小,那么无论哪种方式,性能差异都可能可以忽略不计。
猜你喜欢
  • 2017-12-05
  • 1970-01-01
  • 2015-02-27
  • 2013-05-18
  • 2021-07-08
  • 2018-09-13
  • 1970-01-01
  • 2023-03-14
  • 2015-07-26
相关资源
最近更新 更多