Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to *lazily* iterate on reverse order of keys in OrderedDict?

I'd like to iterate on an OrderedDict in reverse order.

I.e. reverse the order of:

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

So far I've gotten a non-lazy version, by reversing a list:

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

Any ideas how to make it better?

like image 303
Yuval Atzmon Avatar asked Mar 20 '17 04:03

Yuval Atzmon


1 Answers

If you use reversed on the dict it should evaluate lazily:

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

How does this work?

The key element here is a generator expression, which is evaluated lazily. So this will lazily evaluate over the keys of the ordered dict, and then return a tuple of the key and the dict value when needed.

I only need to support python 3:

In python 3, dict.items() is now a view and is evaluated lazily. Thus the above can be simplified to:

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

While Python 2.7 does have a viewitems() method, Python 2.7 OrderedDict views do not support the __reversed__ hook that reversed needs to reverse non-sequences.

like image 87
Stephen Rauch Avatar answered Oct 04 '22 01:10

Stephen Rauch