Last iteration?

Discussion in 'Python' started by Florian Lindner, Oct 12, 2007.

  1. Hello,
    can I determine somehow if the iteration on a list of values is the last
    iteration?

    Example:

    for i in [1, 2, 3]:
    if last_iteration:
    print i*i
    else:
    print i

    that would print

    1
    2
    9


    Can this be acomplished somehow?

    Thanks,

    Florian
     
    Florian Lindner, Oct 12, 2007
    #1
    1. Advertising

  2. Florian Lindner wrote:
    > can I determine somehow if the iteration on a list of values is the last
    > iteration?
    >
    > Example:
    >
    > for i in [1, 2, 3]:
    > if last_iteration:
    > print i*i
    > else:
    > print i
    >
    > that would print
    >
    > 1
    > 2
    > 9
    >
    >
    > Can this be acomplished somehow?


    You could do this:

    l = [1,2,3]
    s = len(l) - 1
    for i, item in enumerate(l): # Py 2.4
    if i == s:
    print item*item
    else:
    print item

    Or, you could look one step ahead:

    l = [1,2,3]
    next = l[0]
    for item in l[1:]:
    print next
    next = item
    print next * next

    Stefan
     
    Stefan Behnel, Oct 12, 2007
    #2
    1. Advertising

  3. Florian Lindner wrote:

    > Hello,
    > can I determine somehow if the iteration on a list of values is the last
    > iteration?
    >
    > Example:
    >
    > for i in [1, 2, 3]:
    > if last_iteration:
    > print i*i
    > else:
    > print i
    >
    > that would print
    >
    > 1
    > 2
    > 9
    >
    >
    > Can this be acomplished somehow?


    def last_iter(iterable):
    it = iter(iterable)
    buffer = [it.next()]
    for i in it:
    buffer.append(i)
    old, buffer = buffer[0], buffer[1:]
    yield False, old
    yield True, buffer[0]



    for last, i in last_iter(xrange(4)):
    if last:
    print i*i
    else:
    print i



    Diez
     
    Diez B. Roggisch, Oct 12, 2007
    #3
  4. Florian Lindner

    Paul Hankin Guest

    On Oct 12, 11:58 am, Florian Lindner <> wrote:
    > Hello,
    > can I determine somehow if the iteration on a list of values is the last
    > iteration?
    >
    > Example:
    >
    > for i in [1, 2, 3]:
    > if last_iteration:
    > print i*i
    > else:
    > print i


    Yes, either use enumerate or just stop the loop early and deal with
    the last element outside the loop.

    xs = [1, 2, 3]
    for x in xs[:-1]:
    print x
    print xs[-1] * xs[-1]

    --
    Paul Hankin
     
    Paul Hankin, Oct 12, 2007
    #4
  5. Florian Lindner

    Guest

    On Oct 12, 11:58 am, Florian Lindner <> wrote:
    > Hello,
    > can I determine somehow if the iteration on a list of values is the last
    > iteration?
    >
    > Example:
    >
    > for i in [1, 2, 3]:
    > if last_iteration:
    > print i*i
    > else:
    > print i
    >
    > that would print
    >
    > 1
    > 2
    > 9
    >
    > Can this be acomplished somehow?
    >


    Another suggestion:

    l = [1, 2, 3]
    for i in l[:-1]: print i
    i = l[-1]
    print i*i


    James
     
    , Oct 12, 2007
    #5
  6. On Fri, 2007-10-12 at 12:58 +0200, Florian Lindner wrote:
    > Hello,
    > can I determine somehow if the iteration on a list of values is the last
    > iteration?
    >
    > Example:
    >
    > for i in [1, 2, 3]:
    > if last_iteration:
    > print i*i
    > else:
    > print i
    >
    > that would print
    >
    > 1
    > 2
    > 9


    Here's another solution:

    mylist = [1,2,3]
    for j,i in reversed(list(enumerate(reversed(mylist)))):
    if j==0:
    print i*i
    else:
    print i

    ;)

    --
    Carsten Haese
    http://informixdb.sourceforge.net
     
    Carsten Haese, Oct 12, 2007
    #6
  7. Florian Lindner

    Paul Hankin Guest

    On Oct 12, 2:18 pm, Carsten Haese <> wrote:
    > On Fri, 2007-10-12 at 12:58 +0200, Florian Lindner wrote:
    > > Hello,
    > > can I determine somehow if the iteration on a list of values is the last
    > > iteration?

    >
    > > Example:

    >
    > > for i in [1, 2, 3]:
    > > if last_iteration:
    > > print i*i
    > > else:
    > > print i

    >
    > > that would print

    >
    > > 1
    > > 2
    > > 9

    >
    > Here's another solution:
    >
    > mylist = [1,2,3]
    > for j,i in reversed(list(enumerate(reversed(mylist)))):
    > if j==0:
    > print i*i
    > else:
    > print i


    Nice! A more 'readable' version is:

    mylist = [1,2,3]
    for not_last, i in reversed(list(enumerate(reversed(mylist)))):
    if not_last:
    print i
    else:
    print i * i

    --
    Paul Hankin
     
    Paul Hankin, Oct 12, 2007
    #7
  8. Florian Lindner

    Peter Otten Guest

    Diez B. Roggisch wrote:

    > Florian Lindner wrote:


    >> can I determine somehow if the iteration on a list of values is the
    >> last iteration?


    > def last_iter(iterable):
    > it = iter(iterable)
    > buffer = [it.next()]
    > for i in it:
    > buffer.append(i)
    > old, buffer = buffer[0], buffer[1:]
    > yield False, old
    > yield True, buffer[0]


    This can be simplified a bit since you never have to remember more than on
    item:

    >>> def mark_last(items):

    .... items = iter(items)
    .... last = items.next()
    .... for item in items:
    .... yield False, last
    .... last = item
    .... yield True, last
    ....
    >>> list(mark_last([]))

    []
    >>> list(mark_last([1]))

    [(True, 1)]
    >>> list(mark_last([1,2]))

    [(False, 1), (True, 2)]

    Peter
     
    Peter Otten, Oct 12, 2007
    #8
  9. On Oct 12, 12:58 pm, Florian Lindner <> wrote:
    > Hello,
    > can I determine somehow if the iteration on a list of values is the last
    > iteration?
    >
    > Example:
    >
    > for i in [1, 2, 3]:
    > if last_iteration:
    > print i*i
    > else:
    > print i
    >
    > that would print
    >
    > 1
    > 2
    > 9
    >
    > Can this be acomplished somehow?
    >
    > Thanks,
    >
    > Florian



    If you want to do this over a list or a string, I'd just do:

    for element in iterable[:-1]: print iterable
    print iterable[-1] * iterable[-1]

    No need for it to get more advanced than that :)
     
    =?iso-8859-1?q?Robin_K=E5veland?=, Oct 13, 2007
    #9
  10. Florian Lindner

    Paul McGuire Guest

    On Oct 12, 5:58 am, Florian Lindner <> wrote:
    > Hello,
    > can I determine somehow if the iteration on a list of values is the last
    > iteration?
    >
    > Example:
    >
    > for i in [1, 2, 3]:
    > if last_iteration:
    > print i*i
    > else:
    > print i
    >
    > that would print
    >
    > 1
    > 2
    > 9
    >
    > Can this be acomplished somehow?
    >
    > Thanks,
    >
    > Florian


    Maybe it's a leftover from my C++ days, but I find the iteration-based
    solutions the most appealing. This is a refinement of the previous
    post by Diez Roggisch. The test method seems to match your desired
    idiom pretty closely:

    def signal_last(lst):
    last2 = None
    it = iter(lst)
    try:
    last = it.next()
    except StopIteration:
    last = None
    for last2 in it:
    yield False, last
    last = last2
    yield True, last

    def test(t):
    for isLast, item in signal_last(t):
    if isLast:
    print "...and the last item is", item
    else:
    print item

    test("ABC")
    test([])
    test([1,2,3])

    Prints:

    A
    B
    ....and the last item is C
    ....and the last item is None
    1
    2
    ....and the last item is 3

    -- Paul
     
    Paul McGuire, Oct 14, 2007
    #10
  11. Florian Lindner

    Paul Hankin Guest

    On Oct 14, 8:00 am, Paul McGuire <> wrote:
    > On Oct 12, 5:58 am, Florian Lindner <> wrote:
    >
    >
    >
    > > Hello,
    > > can I determine somehow if the iteration on a list of values is the last
    > > iteration?

    >
    > > Example:

    >
    > > for i in [1, 2, 3]:
    > > if last_iteration:
    > > print i*i
    > > else:
    > > print i

    >
    > > that would print

    >
    > > 1
    > > 2
    > > 9

    >
    > > Can this be acomplished somehow?

    >
    > > Thanks,

    >
    > > Florian

    >
    > Maybe it's a leftover from my C++ days, but I find the iteration-based
    > solutions the most appealing. This is a refinement of the previous
    > post by Diez Roggisch. The test method seems to match your desired
    > idiom pretty closely:
    >
    > def signal_last(lst):
    > last2 = None
    > it = iter(lst)
    > try:
    > last = it.next()
    > except StopIteration:
    > last = None
    > for last2 in it:
    > yield False, last
    > last = last2
    > yield True, last


    This yields a value when the iterator is empty, which Diez's solution
    didn't. Logically, there is no 'last' element in an empty sequence,
    and it's obscure to add one. Peter Otten's improvement to Diez's code
    looks the best to me: simple, readable and correct.

    --
    Paul Hankin
     
    Paul Hankin, Oct 14, 2007
    #11
  12. Peter Otten schrieb:
    > Diez B. Roggisch wrote:
    >
    >> Florian Lindner wrote:

    >
    >>> can I determine somehow if the iteration on a list of values is the
    >>> last iteration?

    >
    >> def last_iter(iterable):
    >> it = iter(iterable)
    >> buffer = [it.next()]
    >> for i in it:
    >> buffer.append(i)
    >> old, buffer = buffer[0], buffer[1:]
    >> yield False, old
    >> yield True, buffer[0]

    >
    > This can be simplified a bit since you never have to remember more than on
    > item:
    >
    >>>> def mark_last(items):

    > ... items = iter(items)
    > ... last = items.next()
    > ... for item in items:
    > ... yield False, last
    > ... last = item
    > ... yield True, last
    > ...
    >>>> list(mark_last([]))

    > []
    >>>> list(mark_last([1]))

    > [(True, 1)]
    >>>> list(mark_last([1,2]))

    > [(False, 1), (True, 2)]


    Nice.

    I tried to come up with that solution in the first place - but most
    probably due to an java-coding induced brain overload it didn't work
    out:) But I wanted a general purpose based solution to be available that
    doesn't count on len() working on an arbitrary iterable.

    Diez
     
    Diez B. Roggisch, Oct 14, 2007
    #12
  13. Florian Lindner

    Paul McGuire Guest

    On Oct 14, 5:58 am, Paul Hankin <> wrote:
    > On Oct 14, 8:00 am, Paul McGuire <> wrote:
    > > def signal_last(lst):
    > > last2 = None
    > > it = iter(lst)
    > > try:
    > > last = it.next()
    > > except StopIteration:
    > > last = None
    > > for last2 in it:
    > > yield False, last
    > > last = last2
    > > yield True, last

    >
    > This yields a value when the iterator is empty, which Diez's solution
    > didn't. Logically, there is no 'last' element in an empty sequence,
    > and it's obscure to add one. Peter Otten's improvement to Diez's code
    > looks the best to me: simple, readable and correct.
    >


    Of course! For some reason I thought I was improving Peter Otten's
    version, but when I modified my submission to behave as you stated, I
    ended right back with what Peter had submitted. Agreed - nice and
    neat!

    -- Paul
     
    Paul McGuire, Oct 14, 2007
    #13
  14. Florian Lindner

    Peter Otten Guest

    Diez B. Roggisch wrote:

    > out:) But I wanted a general purpose based solution to be available that
    > doesn't count on len() working on an arbitrary iterable.


    You show signs of a severe case of morbus itertools.
    I, too, am affected and have not yet fully recovered...

    Peter
     
    Peter Otten, Oct 15, 2007
    #14
  15. Paul Hankin a écrit :
    > On Oct 12, 11:58 am, Florian Lindner <> wrote:
    >
    >>Hello,
    >>can I determine somehow if the iteration on a list of values is the last
    >>iteration?
    >>
    >>Example:
    >>
    >>for i in [1, 2, 3]:
    >> if last_iteration:
    >> print i*i
    >> else:
    >> print i

    >
    >
    > Yes, either use enumerate or just stop the loop early and deal with
    > the last element outside the loop.
    >
    > xs = [1, 2, 3]
    > for x in xs[:-1]:
    > print x
    > print xs[-1] * xs[-1]


    At least something sensible !-)
     
    Bruno Desthuilliers, Oct 16, 2007
    #15
  16. [Diez B. Roggisch]
    > > out:) But I wanted a general purpose based solution to be available that
    > > doesn't count on len() working on an arbitrary iterable.


    [Peter Otten]
    > You show signs of a severe case of morbus itertools.
    > I, too, am affected and have not yet fully recovered...


    Maybe you guys were secretly yearning for a magical last element
    detector used like this:

    for islast, value in lastdetecter([1,2,3]):
    if islast:
    print 'Last', value
    else:
    print value

    Perhaps it could be written plainly using generators:

    def lastdetecter(iterable):
    it = iter(iterable)
    value = it.next()
    for nextvalue in it:
    yield (False, value)
    value = nextvalue
    yield (True, value)

    Or for those affected by "morbus itertools", a more arcane incantation
    would be preferred:

    from itertools import tee, chain, izip, imap
    from operator import itemgetter

    def lastdetecter(iterable):
    "fast iterator algebra"
    lookahead, t = tee(iterable)
    lookahead.next()
    t = iter(t)
    return chain(izip(repeat(False), imap(itemgetter(1),
    izip(lookahead, t))), izip(repeat(True),t))


    Raymond
     
    Raymond Hettinger, Oct 17, 2007
    #16
  17. > def lastdetecter(iterable):
    > "fast iterator algebra"
    > lookahead, t = tee(iterable)
    > lookahead.next()
    > t = iter(t)
    > return chain(izip(repeat(False), imap(itemgetter(1),
    > izip(lookahead, t))), izip(repeat(True),t))


    More straight-forward version:

    def lastdetecter(iterable):
    t, lookahead = tee(iterable)
    lookahead.next()
    return izip(chain(imap(itemgetter(0), izip(repeat(False),
    lookahead)), repeat(True)), t)


    Raymond
     
    Raymond Hettinger, Oct 17, 2007
    #17
  18. Florian Lindner

    Peter Otten Guest

    Raymond Hettinger wrote:

    > [Diez B. Roggisch]
    >> > out:) But I wanted a general purpose based solution to be available that
    >> > doesn't count on len() working on an arbitrary iterable.

    >
    > [Peter Otten]
    >> You show signs of a severe case of morbus itertools.
    >> I, too, am affected and have not yet fully recovered...

    >
    > Maybe you guys were secretly yearning for a magical last element
    > detector used like this:


    Not secretly...

    > def lastdetecter(iterable):
    > it = iter(iterable)
    > value = it.next()
    > for nextvalue in it:
    > yield (False, value)
    > value = nextvalue
    > yield (True, value)


    as that's what I posted above...

    > def lastdetecter(iterable):
    > "fast iterator algebra"
    > lookahead, t = tee(iterable)


    # make it cope with zero-length iterables
    lookahead = islice(lookahead, 1, None)

    > return chain(izip(repeat(False), imap(itemgetter(1),
    > izip(lookahead, t))), izip(repeat(True),t))


    and that's the "somebody call the doctor -- now!" version ;)

    Peter
     
    Peter Otten, Oct 17, 2007
    #18
  19. Florian Lindner

    Paul Hankin Guest

    On Oct 17, 8:16 am, Raymond Hettinger <> wrote:
    > > def lastdetecter(iterable):
    > > "fast iterator algebra"
    > > lookahead, t = tee(iterable)
    > > lookahead.next()
    > > t = iter(t)
    > > return chain(izip(repeat(False), imap(itemgetter(1),
    > > izip(lookahead, t))), izip(repeat(True),t))

    >
    > More straight-forward version:
    >
    > def lastdetecter(iterable):
    > t, lookahead = tee(iterable)
    > lookahead.next()
    > return izip(chain(imap(itemgetter(0), izip(repeat(False),
    > lookahead)), repeat(True)), t)


    def lastdetector(iterable):
    t, u = tee(iterable)
    return izip(chain(imap(lambda x: False, islice(u, 1, None)),
    [True]), t)

    --
    Paul Hankin
     
    Paul Hankin, Oct 17, 2007
    #19
  20. [Paul Hankin]
    > def lastdetector(iterable):
    > t, u = tee(iterable)
    > return izip(chain(imap(lambda x: False, islice(u, 1, None)),
    > [True]), t)


    Sweet! Nice, clean piece of iterator algebra.

    We need a C-speed verion of the lambda function, something like a K
    combinator that consumes arguments and emits constants.


    Raymond
     
    Raymond Hettinger, Oct 17, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. sangram
    Replies:
    16
    Views:
    2,081
  2. Rudi
    Replies:
    5
    Views:
    5,308
  3. Mike

    Last iteration condition

    Mike, Apr 3, 2007, in forum: Ruby
    Replies:
    12
    Views:
    196
    Robert Klemme
    Apr 3, 2007
  4. Kendall Gifford
    Replies:
    18
    Views:
    276
    paron
    Jun 12, 2009
  5. hymie!

    last iteration of a for loop

    hymie!, Feb 26, 2014, in forum: Perl Misc
    Replies:
    32
    Views:
    367
    Rainer Weikusat
    Mar 6, 2014
Loading...

Share This Page