Re: iterations destroy reversed() results
On Mon, 4 Sept 2023 at 07:44, 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 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
Re: iterations destroy reversed() results
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) > -- https://mail.python.org/mailman/listinfo/python-list
Re: iterations destroy reversed() results
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 > 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
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