Mailing List Archive

iterations destroy reversed() results
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
--
https://mail.python.org/mailman/listinfo/python-list
Re: iterations destroy reversed() results [ In reply 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.

> On 1 Sep 2023, at 19:15, Pierre Fortin via Python-list <python-list@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...
>
> 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
> --
> https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list
Re: iterations destroy reversed() results [ In reply 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'>
>

--
https://mail.python.org/mailman/listinfo/python-list
Re: iterations destroy reversed() results [ In reply to ]
On Mon, 4 Sept 2023 at 07:44, Pierre Fortin via Python-list
<python-list@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
--
https://mail.python.org/mailman/listinfo/python-list