Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to remember the position in a python iterator?

I would like to iterate over an iterable object (let's say, a list) and leave at some point remembering the position where I left off to continue the next time an iterator for that object is called.

Something like:

for val in list:
   do_stuff(val)
   if some_condition:
       break

do_stuff()

for val in list:
    continue_doing_stuff(val)

Speed matters and the list considered is quite large. So saving the object and iterating again through the whole list until the saved element is found is not an option. Is this possible without writing an explicit iterator class for the list?

like image 800
Sofia Bravo Avatar asked Feb 06 '14 04:02

Sofia Bravo


People also ask

Can an iterator go backwards?

A reverse iterator is a kind of iterator, that travels in backwards direction. It means when we increment a reverse_iterator, it goes to the previous element in container. So, to iterate over a vector in reverse direction, we can use the reverse_iterator to iterate from end to start.

What are the 2 methods that an iterator needs to implement in Python?

Iterators are implemented using two special methods in Python which are iter() and next().

Can you get the length of an iterator in Python?

To get the length of an iterator in Python:Use the list() class to convert the iterator to a list. Pass the list to the len() function, e.g. len(list(gen)) . Note that once the iterator is converted to a list, it is exhausted.

What is iteration variable in Python?

The iterator (loop) variable is the variable which stores a portion of the iterable when the for loop is being executed. Each time the loop iterates, the value of the iterator variable will change to a different portion of the iterable.

How do you implement an iterator in Python?

As stated above, a Python iterator object implements a function that needs to carry the exact name __next__. This special function keeps returning elements until it runs out of elements to return, in which case an exception is raised of type StopIteration. To get an iterator object, we need to first call the __iter__ method on an iterable object.

How do you iterate through a list of objects in Python?

Most built-in containers in Python like: list, tuple, string etc. are iterables. The iter () function (which in turn calls the __iter__ () method) returns an iterator from them. We use the next () function to manually iterate through all the items of an iterator.

How does ITER () work in Python?

The iterator calls this function until the returned value is equal to the sentinel. We can see that the int () function always returns 0. So passing it as iter (int,1) will return an iterator that calls int () until the returned value equals 1.

What are iterable objects in Python?

Technically, in Python, an iterator is an object which implements the iterator protocol, which consist of the methods __iter__ () and __next__ (). Lists, tuples, dictionaries, and sets are all iterable objects. They are iterable containers which you can get an iterator from.


2 Answers

The __iter__ method is called when you enter a for loop with an object, returning an iterator. We usually don't keep a name pointing to the iterator, but if we do, we can stop the iterating, do something else, and then resume the iterating.

The best way to get the iterator object is to use the builtin iter function:

a_list = ['a', 'b', 'c', 'd']
iter_list = iter(a_list)

for val in iter_list:
   print(val)                # do_stuff(val)
   if val == 'b':            # some_condition!
       break

print('taking a break')      # do_stuff()

for val in iter_list:
    print(val)               # continue_doing_stuff(val)

shows:

a
b
taking a break
c
d

iter(obj) just returns the result of obj.__iter__(), which should be an iterator implementing a .__next__() method.

That __next__ method is called for each iteration, returning the object (in this case, a character.)

If you want to call the __next__ method yourself instead of having it called by the for loop, you should use the builtin next function:

a_list = ['a', 'b', 'c', 'd']
iter_list = iter(a_list)
print(next(iter_list))       # do_stuff(val)
print(next(iter_list))
print('taking a break')      # do_stuff()
print(next(iter_list))       # continue_doing_stuff(val)
print(next(iter_list))

prints:

a
b
taking a break
c
d
like image 86
Russia Must Remove Putin Avatar answered Oct 15 '22 13:10

Russia Must Remove Putin


You can use a generator to do this

def get_next(iterator):
    for item in iterator:
        yield item

my_list_iterator = get_next(my_list)

for val in my_list_iterator:
    do_stuff(val)
    if some_condition:
        break

do_stuff()

for val in my_list_iterator:
    continue_doing_stuff(val)
like image 28
thefourtheye Avatar answered Oct 15 '22 12:10

thefourtheye