Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

iterations destroy reversed() results

6 views
Skip to first unread message

Pierre Fortin

unread,
Sep 3, 2023, 5:43:30 PM9/3/23
to
Hi,

reversed() results are fine until iterated over, after which the
results are no longer available. This was discovered after using
something like this:

rev = reversed( sorted( list ) )
sr = sum( 1 for _ in rev )
# rev is now destroyed

So reversed() results can only be iterated once unlike sorted(), etc...

Script to illustrate the issue:
/tmp/rev:
orig = [ 'x', 'a', 'y', 'b', 'z', 'c' ]
co = sum( 1 for _ in orig )
print( 'orig', orig, co )
# reversing
rev = reversed(orig)
print( 'before iteration:', [ x for x in rev ] )
# list comprehension was an iteration over 'rev'
print( 'after iteration:', [ x for x in rev ] )
# how this was discovered...
orig = [ 'x', 'a', 'y', 'b', 'z', 'c' ]
rev = reversed(orig)
cr = sum( 1 for _ in rev )
print( 'after sum():', [ x for x in rev ] )

which produces:

$ python /tmp/rev
orig ['x', 'a', 'y', 'b', 'z', 'c'] 6
before iteration: ['c', 'z', 'b', 'y', 'a', 'x']
after iteration: []
after sum(): []

Regards,
Pierre

Dom Grigonis

unread,
Sep 3, 2023, 5:53:25 PM9/3/23
to
It is by design. `sorted` returns a list, while `reversed` returns an iterator. Iterators are exhaust-able, and not reusable. So be mindful of this and if you are going to "re-use” the sequence returned by iterator, convert it to list first.

Have a look at `itertools` library, which contains a lot of such functions and many good recipes on achieving various things elegantly using iterators.
> --
> https://mail.python.org/mailman/listinfo/python-list

Thomas Passin

unread,
Sep 3, 2023, 6:37:11 PM9/3/23
to
On 9/1/2023 12:15 PM, Pierre Fortin via Python-list wrote:
> Hi,
>
> reversed() results are fine until iterated over, after which the
> results are no longer available. This was discovered after using
> something like this:
>
> rev = reversed( sorted( list ) )
> sr = sum( 1 for _ in rev )
> # rev is now destroyed
>
> So reversed() results can only be iterated once unlike sorted(), etc...

reversed() is an iterator these days:

>>> l1 = [1, 2, 3]
>>> rev = reversed( sorted( l1 ) )
>>> type(rev)
<class 'list_reverseiterator'>
>

Chris Angelico

unread,
Sep 3, 2023, 6:43:15 PM9/3/23
to
On Mon, 4 Sept 2023 at 07:44, Pierre Fortin via Python-list
<pytho...@python.org> wrote:
>
> Hi,
>
> reversed() results are fine until iterated over, after which the
> results are no longer available. This was discovered after using
> something like this:
>
> rev = reversed( sorted( list ) )
> sr = sum( 1 for _ in rev )
> # rev is now destroyed
>
> So reversed() results can only be iterated once unlike sorted(), etc...

reversed() is like iter(), and should be used the same way:

for item in reversed(list):

If you want to eagerly construct a full reversed list, instead slice the list:

list[::-1]

ChrisA
0 new messages