简体   繁体   中英

How is a rangeiterator implemented in Python?

>>> reversed(xrange(100))
<rangeiterator object at 0xb72aab78>
>>> it = reversed(xrange(100)).__iter__()
>>> it
<rangeiterator object at 0xb72aa4d0>
>>> next(it)
99

How can I implement something like this in Python? To be more spesific, how can I make an iterator, that could be reversed without it being made a list in the memory before it could get reversed?

Basically, you implement the __reversed__ magic method on the collection.

The logic for xrange is something like:

def __reversed__(self):
    return iter(xrange(stop - 1, start - 1, step * -1))

There is no trick -- you need to know how to produce a reverse iterator. Python doesn't do it for you.

If your iterator implements the method __reversed__() , this will be used by the builtin reversed() . xrange() returns iterators which do that.

reversed will work with two types of object:

  • a sequence (such as a list )
  • an iterator with the __reversed__ magic method

If you have a custom sequence, and you can take the len() of that sequence, you are good to go -- otherwise, you need to add the __len__ magic method; if you cannot (eg because the length is not known), then you cannot reverse it lazily.

If you have a custom iterator, then make sure it has the __reversed__ magic method: __reversed__ must return a new iterator that goes backwards; again, if you cannot provide one (eg because the length is not known), then you cannot lazily reverse it.

Note : for more info about creating custom iterables see this answer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM