Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
iincomplete terators
#1
i would like to iterate over an iterator and then deal with it (the iterator itself), such as return it, in its incomplete (not iterated all the way) state. what i have been doing is making it into a list (using comprehension as i have found that some iterator classes "leak" through a list() call), popping elements as they are used, and using the incomplete list:
    ...
    mylist = [x for x in myiter]
    while mylist:
       thing = mylist.pop(0)
       result = testit(thing)
       if result:
           return mylist, result, thing
       ...
i am looking for how i might do:
    ...
    for thing in mylist:
       result = testit(thing)
       if result:
           return ...
so the big question is: is there a way to get (and pass along like return) the iterated state of any iterator? anything that can be iterated has to be storing that iteration state somewhere. is that accessible?

can i duplicate/replicate a generator part way through it doing its generating thing?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
Calling iter() should work
def func(seq):
    seq = iter(seq)
    for thing in seq:
        if thing == 'w':
            return seq, thing
        
s, t = func('hello world')
print(list(s))
Output:
['o', 'r', 'l', 'd']
Reply
#3
def beyond(a,b):
    for c in a:
        if c == b:
            return iterstate(a)
...
y = [x for x in beyond([1,2,3,4,5,6],3)]
print(repr(y))
with that example i should get [4, 5, 6] for output. but in this case, it is a list. i'd want something that works with any iterator, to duplicate it, including its current iteration state.

the iteration state, alone, should be considered meaningless, to any other iterator. this should be especially obvious for generators.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#4
Why don't you call iter() as in the above code
def beyond(a,b):
    a = iter(a)
    for c in a:
        if c == b:
            return a

y = [x for x in beyond([1,2,3,4,5,6],3)]
print(repr(y))
Output:
[4, 5, 6]
There is also
import itertools as it

def beyond(a, b):
    return it.islice(it.dropwhile(lambda x: x != b, a), 1, None)
or even
import functools as fu
import itertools as it
import operator as op

def beyond(a, b):
    return it.islice(it.dropwhile(fu.partial(op.ne, b), a), 1, None)
Reply
#5
i tried iter() like this:

def funny(x):
    for v in x:
        i = iter(x)
        for u in i:
            print(v,u)

funny([1,2,3,4,5])
print('done')
but iter(x) just duplicated x at its initial state. i guess i do not understand how this is used.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#6
(Mar-27-2018, 05:51 AM)Skaperen Wrote: i guess i do not understand how this is used.
If x is a list, iter(x) returns an iterator pointing to x that also stores an "iteration state" (probably an integer index). When you call for v in x, what python actualy does is for v in iter(x), that is to say it creates an iterator. This is the "iterator protocol". Use your favorite search engine with these words.
Reply
#7
what if x is not a list?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#8
(Mar-28-2018, 12:19 AM)Skaperen Wrote: what if x is not a list?
Then iter(x) returns the appropriate iterator object for this type, which encapsulate the state of the iteration. You can use this protocol by implementing __iter__() and __next__() method for your classes and your iterator classes.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020