I am new to learn python these days. While reading a book, I found a line of code that I can't understand. Please see line 46 under print_progression() method, print(' '.join(str(next(self)) for j in range(n))).
class Progression:
    '''Iterator producing a generic progression.
    Default iterator produces the whole number, 0, 1, 2, ...
    '''
def __init__(self, start = 0):
    '''
    Initialize current to the first value of the progression.
    '''
    self._current = start
def _advance(self):
    '''
    Update self.current to a new value.
    This should be overriden by a subclass to customize progression.
    By convension, if current is set to None, this designates the
    end of a finite progression.
    '''
    self._current += 1
def __next__(self):
    '''
    Return the next element, or else raise StopIteration error.
    '''
    # Our convention to end a progression
    if self._current is None:
        raise StopIteration()
    else:
        # record current value to return
        answer = self._current
        # advance to prepare for next time
        self._advance()
        # return the answer
        return answer
def __iter__(self):
    '''
    By convention, an iterator must return itself as an iterator.
    '''
    return self
def print_progression(self, n):
    '''
    Print next n values of the progression.
    '''
    print(' '.join(str(next(self)) for j in range(n)))
class ArithmeticProgression(Progression): # inherit from Progression
    pass
if __name__ == '__main__':
    print('Default progression:')
    Progression().print_progression(10)
'''Output is
Default progression:
0 1 2 3 4 5 6 7 8 9 10'''
I have no idea how next(self) and j works.
- I think it should be str(Progression.next()). (solved) 
- I cannot find j anywhere. What is j for? Why not using while loop such as while Progression.next() <= range(n)? 
For my final thought, it should be
print(' '.join(str(next(self)) while next(self) <= range(n)))
Save this newbie.
Thanks in advance!
 
     
     
    