+2

# Reverse iterator

Ladies and Gentlman, who knows, how to make reverse iterator without using reverse function. The meaning is: regular iterator takes elements from list one by one, from 1st till last, but i need opposite from last till 1st.

12/12/2019 4:05:52 PM

Оксана Кувыркова

+9

Оксана Кувыркова l = [2,4,6,8] # normal iterator for i in l: print(i) # reversed iterator print() for i in l[::-1]: print(i)

+7

This sample is using a generator : res = (i for i in lst[::-1]) for i in res: print(i, end=', ') # or the short way: for i in (i for i in lst[::-1]): print(i, end=', ')

+6

You can also use range: lst = [3,2,6,4,9] for i in range(len(lst)-1,-1,-1): print(lst[i], end=', ')

+6

Are these iterators though? Both seem to be iterables rather. EDIT: I regoogled a bit, and it just increased my confusion. Iterator, iterable, generator etc. ... people seem to use these terms in slightly different ways. The thing about reversed is that it doesn't create a new collection - it is just a 'manual', that says how a collection is supposed to be walked through - backwards. This can be memory-saving, because all that data doesn't have to be copied. x[::-1] on the other hand creates a whole new list, so you end up with two equal objects, only that one is inverted. range creates a range of numbers, that is then used to walk through the collection backwards - it comes closer to reversed, but is still not the same thing. If the task was just to 'walk through backwards', the answers are fine. If the idea was not to create a whole new object... well then you might need something else.

+5

So like this for getting by the copy? # basically an imitation of reversed def rev(iterable): i = len(iterable) while i: i -= 1 yield iterable[i] list_ = [1, 2, 3] it = rev(list_) print(*it)

+4

l = [2,4,6,8] # normal iterator for i in l: print(i) # reversed iterator print() for i in range(len(l)-1,-1,-1): print(l[i])

+4

Hi HonFu, I was pretty sure that working with slices don't generate copies. I found this at stack overflow: "Slicing lists does not generate copies of the objects in the list; it just copies the references to them." For reference: https://stackoverflow.com/questions/5131538/slicing-a-list-in-python-without-generating-a-copy

+3

HonFu, i have a question, if it is generator it mast have yield? So far your last code is perfect for my generator modification, but i cannot mark your answer as best for it, because question was about iterator and that answer of Jan was exact.

+3

Don't worry about best answer. :) Just ask yourself what the original task meant, and choose accordingly: 1.) Did they want a copy? 2.) Did they just want to walk over it backwards? 3.) Or did they want to have an object that does the walking? If you want to write a generator function, then you must use yield. When you use a generator expression (n for n in whatever), you don't need yield.

+2

Woooow, excellent! Thank you

+2

It is great, i will need it next!

+2

Lothar, I am wondering though: True, res will be a generator/iterator whatever, but it will be created out of lst[::-1] which is already a copy, right? So you'd end up making a copy anyway.

+2

Lothar, that's a nice link, thank you! Yeah, in Python we have references only, and it's better to just copy the references than the whole objects (at least when they are big). Yet the point of the whole generator business is to prevent the copying of whole collections (and be it references), right? Instead you only have an instruction that will produce the value 'only when needed'. And that's what reversed does, but slice doesn't. Run these two code snippets to compare: a = [1, 2, 3] b = reversed(a) a[0] = 42 print(*b) # Output: [3, 2, 42] a = [1, 2, 3] b = a[::-1] a[0] = 42 print(*b) # Output: [3, 2, 1]

+2

HonFu excellent example! I wondered what difference, if any, using a method vs slicing has. This illustrates the difference in a very meaningful way?! Thank you! Lothar I also Thank You for that link. I know I have read all this before, but I think I needed a reminder to review?! Great stuff! 😎👍

+1

+1

If you're working with iterators,then you need to convert the list into an iterable..using..iter(list_name)

0

Thank you, but i cannot use reverse, i need to solve in other way

0

O, looks good, let me try

0

I needed to use >iter< so with this help it have been solved. Thank you for quick help