user1050619
user1050619

Reputation: 20856

Stopiteration identfying the iterable object

I have 2 generator and using the next method & while loop to process thru it as below,

code

while end_of_loop = 'n':
    try:
        table1_row = next(table1_generator)
        table2_row = next(table2_generator)
    except StopIteration:
        end_of_loop = 'y'

How do I identify which iterator object has no rows?

Im trying to compare 2 tables and each table rows are in generator objects.

def _compare(self):
        end_of_table = 'N'

        try:
            while end_of_table =='N':
                try:
                    if self.table1_key == self.table2_key:
                        print 'same key'
                        self.table1_row = next(self.table1_generator)
                        self._convert_table1_key_fields()
                        self.table2_row = next(self.table2_generator)
                        self._convert_table2_key_fields()
                    elif self.table1_key > self.table2_key:
                        self.table2_row = next(self.table1_generator)
                        self._convert_table2_key_fields()
                    elif self.table1_key < self.table2_key:
                        self.table1_row = next(self.table2_generator)
                        self._convert_table1_key_fields()
                except StopIteration as e:
                    print e.args
                    print 'IterError'
                    end_of_table = 'y'

        except StopIteration:
            print 'Next Iteration'

Upvotes: 2

Views: 88

Answers (3)

georg
georg

Reputation: 214949

I can't think of a use case for this (care to share?), but I'd try wrapping next into my own function:

def mynext(it):
    try:
        return next(it)
    except StopIteration:
        raise StopIteration(it)

and then, for example,

a = iter([1,2,3,4,5])
b = iter([4,5,6,7])

try:
    while True:
        print mynext(a)
        print mynext(b)
except StopIteration as e:
    if e.args[0] == a: print 'a ended' 
    if e.args[0] == b: print 'b ended' 

Upvotes: 1

mgilson
mgilson

Reputation: 309889

You can provide a second "sentinel" value to next:

sentinel = object()
while end_of_loop = 'n':

    table1_row = next(table1_generator,sentinel)
    table2_row = next(table2_generator,sentinel)

    #I don't account for the case where they could be exhausted at 
    #the same time.  It's easy to add that if it matters though.
    if table1_row is sentinel:
       print "table1_generator gave up first"
       #"break" might be more appropriate ... 
       #(Unless there more to the loop than this.)
       end_of_loop = 'y'    
    elif table2_row is sentinel:
       print "table2_generator gave up first"
       end_of_loop = 'y'

Upvotes: 4

shx2
shx2

Reputation: 64318

You didn't provide details about the context or what you're actually trying to do, but it sounds like itertools.izip_longest might be useful in your case (and more pythonic). You can fill with Nones or another value which is suitable.

Upvotes: 2

Related Questions