【问题标题】:How to *lazily* iterate on reverse order of keys in OrderedDict?如何 *lazily* 迭代 OrderedDict 中键的相反顺序?
【发布时间】:2017-03-20 04:58:52
【问题描述】:

我想以相反的顺序迭代 OrderedDict

即颠倒顺序:

for k, v in my_ordered_dict.iteritems():
   # < do stuff >

到目前为止,我通过反转列表获得了一个非惰性版本:

for k, v in list(my_ordered_dict.iteritems())[::-1]:
   # < do stuff >

有什么办法可以让它变得更好吗?

【问题讨论】:

  • @sayth,这是一个不同的问题
  • reverse() 并不懒惰 - 它需要评估整个 iterable 以将其以相反的顺序返回,for k, v in reversed(my_ordered_dict.iteritems()) 是您能做的最好的事情。
  • @AChampion,在这种情况下,reversed(my_ordered_dict.iteritems()) 等同于list(my_ordered_dict.iteritems())[::-1]
  • TIL:这让reversed() 成为更好的选择。

标签: python dictionary ordereddictionary


【解决方案1】:

如果您在 dict 上使用 reversed,它应该会延迟评估:

for k, v in ((k, my_ordered_dict[k]) for k in reversed(my_ordered_dict)):
    .....

这是如何工作的?

这里的关键元素是generator expression,它是惰性求值的。所以这将懒惰地评估有序字典的键,然后在需要时返回键的 tupledict 值。

我只需要支持python 3:

在 python 3 中,dict.items() 现在是一个视图,并且被延迟评估。因此上面可以简化为:

for k, v in reversed(my_ordered_dict.items()):

虽然 Python 2.7 确实有一个 viewitems() 方法,但 Python 2.7 OrderedDict 视图不支持 __reversed__ 钩子,reversed 需要反转非序列。

【讨论】:

  • 你能把它进一步简化为for k, v in reversed(my_ordered_dict.items()): 吗?
  • 那么为什么 for k, v in reversed(my_ordered_dict.iteritems()) 不能为 Py2 工作?
  • @AChampion: reversed 不接受迭代器。 (viewitems 也不起作用,因为 Python 2 OrderedDict 视图不支持 __reversed__。)
  • 好点。然后for k in reversed(my_ordered_dict): v = my_ordered_dict[k] ...,因为OrderedDict 确实有__reversed__() Py2。
【解决方案2】:

您可以在值的范围内,然后从值的数量中减去。

items = my_ordered_dict.iteritems()
max_index = len(items)

for i in range(max_index):
    object = items[max_index - i - 1]

【讨论】:

  • 在 Python 2.7 中——看起来你正在使用它——max_index = len(items) -> TypeError: object of type 'generator' has no len()。在 Python 3 中,使用 my_ordered_dict.items() 会导致 TypeError: 'odict_items' object does not support indexing 用于行 object = items[max_index - i - 1]
猜你喜欢
  • 2012-01-09
  • 2013-05-18
  • 1970-01-01
  • 2012-05-22
  • 2015-12-09
  • 1970-01-01
  • 2019-01-15
  • 1970-01-01
  • 2017-05-28
相关资源
最近更新 更多