如何在有序字典中进行反向迭代并且实现惰性求值?

7
我想要对一个OrderedDict进行反向迭代。
即将以下顺序反转:
for k, v in my_ordered_dict.iteritems():
   # < do stuff >

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

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

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

请尝试访问https://dev59.com/9XA75IYBdhLWcg3wkZ-A#3221487 - sayth
1
@sayth,这是一个不同的问题。 - Yuval Atzmon
@AChampion,在这种情况下,reversed(my_ordered_dict.iteritems())等同于list(my_ordered_dict.iteritems())[::-1]吗? - Yuval Atzmon
不,这会创建两个列表,一个用于 list(),另一个用于 [::-1],而 reversed(...) 只创建一个列表。 - AChampion
1
TIL:这使得reversed()成为更好的选择。 - AChampion
显示剩余2条评论
2个回答

14

如果在字典上使用reversed,它应该被惰性计算:

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

这个是如何工作的?

关键在于 生成器表达式,它被惰性地评估。 因此,它会惰性地遍历有序字典的键,然后在需要时返回键和 dict 值的 tuple

我只需要支持 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需要反转非序列的。


1
你能进一步简化成 for k, v in reversed(my_ordered_dict.items()): 吗? - maxymoo
为什么 for k, v in reversed(my_ordered_dict.iteritems()) 在 Py2 上不能工作呢? - AChampion
@AChampion:reversed不接受迭代器。(viewitems也不行,因为Python 2的有序字典视图不支持__reversed__。) - user2357112
不错。然后 for k in reversed(my_ordered_dict): v = my_ordered_dict[k] ...,因为 OrderedDict 在 Py2 中确实有 __reversed__() 方法。 - AChampion

-2
你可以使用range函数来获取值,然后从值的数量中减去。
items = my_ordered_dict.iteritems()
max_index = len(items)

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

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] - martineau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接