Is is safe to use next within a for loop in Python?











up vote
9
down vote

favorite
3












Consider the following Python code:



b = [1,2,3,4,5,6,7]
a = iter(b)
for x in a :
if (x % 2) == 0 :
print(next(a))


Which will print 3, 5, and 7. Is the use of next on the variable being iterated on a reliable construct (you may assume that a StopIteration exception is not a concern or will be handled), or does the modification of the iterator being looped over inside the loop constitute a violation of some principle?










share|improve this question






















  • A question to ponder: what happens if you skip the if condition and always call next(a)?
    – Daniel Roseman
    2 hours ago








  • 4




    That's fine as long as you know what you're getting into.
    – timgeb
    2 hours ago






  • 3




    Ok, but worth commenting if others are going to be using/reading the code.
    – snakecharmerb
    2 hours ago















up vote
9
down vote

favorite
3












Consider the following Python code:



b = [1,2,3,4,5,6,7]
a = iter(b)
for x in a :
if (x % 2) == 0 :
print(next(a))


Which will print 3, 5, and 7. Is the use of next on the variable being iterated on a reliable construct (you may assume that a StopIteration exception is not a concern or will be handled), or does the modification of the iterator being looped over inside the loop constitute a violation of some principle?










share|improve this question






















  • A question to ponder: what happens if you skip the if condition and always call next(a)?
    – Daniel Roseman
    2 hours ago








  • 4




    That's fine as long as you know what you're getting into.
    – timgeb
    2 hours ago






  • 3




    Ok, but worth commenting if others are going to be using/reading the code.
    – snakecharmerb
    2 hours ago













up vote
9
down vote

favorite
3









up vote
9
down vote

favorite
3






3





Consider the following Python code:



b = [1,2,3,4,5,6,7]
a = iter(b)
for x in a :
if (x % 2) == 0 :
print(next(a))


Which will print 3, 5, and 7. Is the use of next on the variable being iterated on a reliable construct (you may assume that a StopIteration exception is not a concern or will be handled), or does the modification of the iterator being looped over inside the loop constitute a violation of some principle?










share|improve this question













Consider the following Python code:



b = [1,2,3,4,5,6,7]
a = iter(b)
for x in a :
if (x % 2) == 0 :
print(next(a))


Which will print 3, 5, and 7. Is the use of next on the variable being iterated on a reliable construct (you may assume that a StopIteration exception is not a concern or will be handled), or does the modification of the iterator being looped over inside the loop constitute a violation of some principle?







python






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 2 hours ago









Jack Aidley

11.3k42858




11.3k42858












  • A question to ponder: what happens if you skip the if condition and always call next(a)?
    – Daniel Roseman
    2 hours ago








  • 4




    That's fine as long as you know what you're getting into.
    – timgeb
    2 hours ago






  • 3




    Ok, but worth commenting if others are going to be using/reading the code.
    – snakecharmerb
    2 hours ago


















  • A question to ponder: what happens if you skip the if condition and always call next(a)?
    – Daniel Roseman
    2 hours ago








  • 4




    That's fine as long as you know what you're getting into.
    – timgeb
    2 hours ago






  • 3




    Ok, but worth commenting if others are going to be using/reading the code.
    – snakecharmerb
    2 hours ago
















A question to ponder: what happens if you skip the if condition and always call next(a)?
– Daniel Roseman
2 hours ago






A question to ponder: what happens if you skip the if condition and always call next(a)?
– Daniel Roseman
2 hours ago






4




4




That's fine as long as you know what you're getting into.
– timgeb
2 hours ago




That's fine as long as you know what you're getting into.
– timgeb
2 hours ago




3




3




Ok, but worth commenting if others are going to be using/reading the code.
– snakecharmerb
2 hours ago




Ok, but worth commenting if others are going to be using/reading the code.
– snakecharmerb
2 hours ago












3 Answers
3






active

oldest

votes

















up vote
6
down vote













There's nothing wrong here protocol-wise or in theory that would stop you from writing such code. An exhausted iterator it will throw StopIteration on every subsequent call to it.__next__, so the for loop technically won't mind if you exhaust the iterator with a next/__next__ call in the loop body.



I advise against writing such code because the program will be very hard to reason about. If the scenario gets a little more complex than what you are showing here, at least I would have to go through some inputs with pen and paper and work out what's happening.



In fact, your code snippet possibly does not even behave like you think it behaves, assuming you want to print every number that is preceded by an even number.



>>> b = [1, 2, 4, 7, 8]                                              
>>> a = iter(b)
>>> for x in a:
...: if x%2 == 0:
...: print(next(a, 'stop'))
4
stop


Why is 7 skipped although it's preceded by the even number 4?



>>>> a = iter(b)                                                      
>>>> for x in a:
...: print('for loop assigned x={}'.format(x))
...: if x%2 == 0:
...: nxt = next(a, 'stop')
...: print('if popped nxt={} from iterator'.format(nxt))
...: print(nxt)
...:
for loop assigned x=1
for loop assigned x=2
if popped nxt=4 from iterator
4
for loop assigned x=7
for loop assigned x=8
if popped nxt=stop from iterator
stop


Turns out x = 4 is never assigned by the for loop because the explicit next call popped that element from the iterator before the for loop had a chance to look at the iterator again.



That's something I'd hate to work out the details of when reading code.






share|improve this answer





















  • The example above is, of course, a toy, you can see the motivating example here: stackoverflow.com/questions/53762253/… where the asker wants to search for a particular sequence in one line and print the next.
    – Jack Aidley
    27 mins ago










  • @JackAidley Usually, in cases like these, I believe the pattern to zip the list with itself, offset by one is interesting. For instance, you could do : for previous, current in zip(my_list, my_list[1:]):. This prevents you from doing fancy tricks with next, and is quite readable and elegant.
    – Vincent Savard
    20 mins ago












  • @VincentSavard There's also the pairwise recipe which works with any iterable (iterators included).
    – timgeb
    7 mins ago










  • @VincentSavard This doesn't work when reading lines from a file, however.
    – Jack Aidley
    7 mins ago










  • @JackAidley Why wouldn't it work? You can read the first two lines to create the first element, then it's just a matter of reading the file line by line.
    – Vincent Savard
    3 mins ago


















up vote
1
down vote













It depends what you mean by 'safe', as others have commented, it is okay, but you can imagine some contrived situations that might catch you out, for example consider this code snippet:



b = [1,2,3,4,5,6,7]
a = iter(b)
def yield_stuff():
for item in a:
print(item)
print(next(a))
yield 1

list(yield_stuff())


On Python <= 3.6 it runs and outputs:



1
2
3
4
5
6
7


But on Python 3.7 it raises RuntimeError: generator raised StopIteration. Of course this is expected if you read PEP 479 and if you're thinking about handling StopIteration anyway you might never encounter it, but I guess the use cases for calling next() inside a for loop are rare and there are normally clearer ways of re-factoring the code.






share|improve this answer




























    up vote
    1
    down vote













    If you modify you code to see what happens to iterator a:



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

    for x in a :
    print 'x', x
    if (x % 2) == 0 :
    print 'a', next(a)


    You will see the printout:



    x 1
    x 2
    a 3
    x 4
    a 5
    x 6
    a 7


    It means that when you are doing next(a) you are moving forward your iterator. If you need (or will need in the future) to do something else with iterator a, you will have problems. For complete safety use various recipes from itertools module. For example:



    from itertools import tee, izip

    def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

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

    for x, next_x in c:
    if x % 2 == 0:
    print next_x


    Not that here you have full control in any place of the cycle either on current iterator element, or next one.






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53764256%2fis-is-safe-to-use-next-within-a-for-loop-in-python%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      6
      down vote













      There's nothing wrong here protocol-wise or in theory that would stop you from writing such code. An exhausted iterator it will throw StopIteration on every subsequent call to it.__next__, so the for loop technically won't mind if you exhaust the iterator with a next/__next__ call in the loop body.



      I advise against writing such code because the program will be very hard to reason about. If the scenario gets a little more complex than what you are showing here, at least I would have to go through some inputs with pen and paper and work out what's happening.



      In fact, your code snippet possibly does not even behave like you think it behaves, assuming you want to print every number that is preceded by an even number.



      >>> b = [1, 2, 4, 7, 8]                                              
      >>> a = iter(b)
      >>> for x in a:
      ...: if x%2 == 0:
      ...: print(next(a, 'stop'))
      4
      stop


      Why is 7 skipped although it's preceded by the even number 4?



      >>>> a = iter(b)                                                      
      >>>> for x in a:
      ...: print('for loop assigned x={}'.format(x))
      ...: if x%2 == 0:
      ...: nxt = next(a, 'stop')
      ...: print('if popped nxt={} from iterator'.format(nxt))
      ...: print(nxt)
      ...:
      for loop assigned x=1
      for loop assigned x=2
      if popped nxt=4 from iterator
      4
      for loop assigned x=7
      for loop assigned x=8
      if popped nxt=stop from iterator
      stop


      Turns out x = 4 is never assigned by the for loop because the explicit next call popped that element from the iterator before the for loop had a chance to look at the iterator again.



      That's something I'd hate to work out the details of when reading code.






      share|improve this answer





















      • The example above is, of course, a toy, you can see the motivating example here: stackoverflow.com/questions/53762253/… where the asker wants to search for a particular sequence in one line and print the next.
        – Jack Aidley
        27 mins ago










      • @JackAidley Usually, in cases like these, I believe the pattern to zip the list with itself, offset by one is interesting. For instance, you could do : for previous, current in zip(my_list, my_list[1:]):. This prevents you from doing fancy tricks with next, and is quite readable and elegant.
        – Vincent Savard
        20 mins ago












      • @VincentSavard There's also the pairwise recipe which works with any iterable (iterators included).
        – timgeb
        7 mins ago










      • @VincentSavard This doesn't work when reading lines from a file, however.
        – Jack Aidley
        7 mins ago










      • @JackAidley Why wouldn't it work? You can read the first two lines to create the first element, then it's just a matter of reading the file line by line.
        – Vincent Savard
        3 mins ago















      up vote
      6
      down vote













      There's nothing wrong here protocol-wise or in theory that would stop you from writing such code. An exhausted iterator it will throw StopIteration on every subsequent call to it.__next__, so the for loop technically won't mind if you exhaust the iterator with a next/__next__ call in the loop body.



      I advise against writing such code because the program will be very hard to reason about. If the scenario gets a little more complex than what you are showing here, at least I would have to go through some inputs with pen and paper and work out what's happening.



      In fact, your code snippet possibly does not even behave like you think it behaves, assuming you want to print every number that is preceded by an even number.



      >>> b = [1, 2, 4, 7, 8]                                              
      >>> a = iter(b)
      >>> for x in a:
      ...: if x%2 == 0:
      ...: print(next(a, 'stop'))
      4
      stop


      Why is 7 skipped although it's preceded by the even number 4?



      >>>> a = iter(b)                                                      
      >>>> for x in a:
      ...: print('for loop assigned x={}'.format(x))
      ...: if x%2 == 0:
      ...: nxt = next(a, 'stop')
      ...: print('if popped nxt={} from iterator'.format(nxt))
      ...: print(nxt)
      ...:
      for loop assigned x=1
      for loop assigned x=2
      if popped nxt=4 from iterator
      4
      for loop assigned x=7
      for loop assigned x=8
      if popped nxt=stop from iterator
      stop


      Turns out x = 4 is never assigned by the for loop because the explicit next call popped that element from the iterator before the for loop had a chance to look at the iterator again.



      That's something I'd hate to work out the details of when reading code.






      share|improve this answer





















      • The example above is, of course, a toy, you can see the motivating example here: stackoverflow.com/questions/53762253/… where the asker wants to search for a particular sequence in one line and print the next.
        – Jack Aidley
        27 mins ago










      • @JackAidley Usually, in cases like these, I believe the pattern to zip the list with itself, offset by one is interesting. For instance, you could do : for previous, current in zip(my_list, my_list[1:]):. This prevents you from doing fancy tricks with next, and is quite readable and elegant.
        – Vincent Savard
        20 mins ago












      • @VincentSavard There's also the pairwise recipe which works with any iterable (iterators included).
        – timgeb
        7 mins ago










      • @VincentSavard This doesn't work when reading lines from a file, however.
        – Jack Aidley
        7 mins ago










      • @JackAidley Why wouldn't it work? You can read the first two lines to create the first element, then it's just a matter of reading the file line by line.
        – Vincent Savard
        3 mins ago













      up vote
      6
      down vote










      up vote
      6
      down vote









      There's nothing wrong here protocol-wise or in theory that would stop you from writing such code. An exhausted iterator it will throw StopIteration on every subsequent call to it.__next__, so the for loop technically won't mind if you exhaust the iterator with a next/__next__ call in the loop body.



      I advise against writing such code because the program will be very hard to reason about. If the scenario gets a little more complex than what you are showing here, at least I would have to go through some inputs with pen and paper and work out what's happening.



      In fact, your code snippet possibly does not even behave like you think it behaves, assuming you want to print every number that is preceded by an even number.



      >>> b = [1, 2, 4, 7, 8]                                              
      >>> a = iter(b)
      >>> for x in a:
      ...: if x%2 == 0:
      ...: print(next(a, 'stop'))
      4
      stop


      Why is 7 skipped although it's preceded by the even number 4?



      >>>> a = iter(b)                                                      
      >>>> for x in a:
      ...: print('for loop assigned x={}'.format(x))
      ...: if x%2 == 0:
      ...: nxt = next(a, 'stop')
      ...: print('if popped nxt={} from iterator'.format(nxt))
      ...: print(nxt)
      ...:
      for loop assigned x=1
      for loop assigned x=2
      if popped nxt=4 from iterator
      4
      for loop assigned x=7
      for loop assigned x=8
      if popped nxt=stop from iterator
      stop


      Turns out x = 4 is never assigned by the for loop because the explicit next call popped that element from the iterator before the for loop had a chance to look at the iterator again.



      That's something I'd hate to work out the details of when reading code.






      share|improve this answer












      There's nothing wrong here protocol-wise or in theory that would stop you from writing such code. An exhausted iterator it will throw StopIteration on every subsequent call to it.__next__, so the for loop technically won't mind if you exhaust the iterator with a next/__next__ call in the loop body.



      I advise against writing such code because the program will be very hard to reason about. If the scenario gets a little more complex than what you are showing here, at least I would have to go through some inputs with pen and paper and work out what's happening.



      In fact, your code snippet possibly does not even behave like you think it behaves, assuming you want to print every number that is preceded by an even number.



      >>> b = [1, 2, 4, 7, 8]                                              
      >>> a = iter(b)
      >>> for x in a:
      ...: if x%2 == 0:
      ...: print(next(a, 'stop'))
      4
      stop


      Why is 7 skipped although it's preceded by the even number 4?



      >>>> a = iter(b)                                                      
      >>>> for x in a:
      ...: print('for loop assigned x={}'.format(x))
      ...: if x%2 == 0:
      ...: nxt = next(a, 'stop')
      ...: print('if popped nxt={} from iterator'.format(nxt))
      ...: print(nxt)
      ...:
      for loop assigned x=1
      for loop assigned x=2
      if popped nxt=4 from iterator
      4
      for loop assigned x=7
      for loop assigned x=8
      if popped nxt=stop from iterator
      stop


      Turns out x = 4 is never assigned by the for loop because the explicit next call popped that element from the iterator before the for loop had a chance to look at the iterator again.



      That's something I'd hate to work out the details of when reading code.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered 1 hour ago









      timgeb

      47.8k116288




      47.8k116288












      • The example above is, of course, a toy, you can see the motivating example here: stackoverflow.com/questions/53762253/… where the asker wants to search for a particular sequence in one line and print the next.
        – Jack Aidley
        27 mins ago










      • @JackAidley Usually, in cases like these, I believe the pattern to zip the list with itself, offset by one is interesting. For instance, you could do : for previous, current in zip(my_list, my_list[1:]):. This prevents you from doing fancy tricks with next, and is quite readable and elegant.
        – Vincent Savard
        20 mins ago












      • @VincentSavard There's also the pairwise recipe which works with any iterable (iterators included).
        – timgeb
        7 mins ago










      • @VincentSavard This doesn't work when reading lines from a file, however.
        – Jack Aidley
        7 mins ago










      • @JackAidley Why wouldn't it work? You can read the first two lines to create the first element, then it's just a matter of reading the file line by line.
        – Vincent Savard
        3 mins ago


















      • The example above is, of course, a toy, you can see the motivating example here: stackoverflow.com/questions/53762253/… where the asker wants to search for a particular sequence in one line and print the next.
        – Jack Aidley
        27 mins ago










      • @JackAidley Usually, in cases like these, I believe the pattern to zip the list with itself, offset by one is interesting. For instance, you could do : for previous, current in zip(my_list, my_list[1:]):. This prevents you from doing fancy tricks with next, and is quite readable and elegant.
        – Vincent Savard
        20 mins ago












      • @VincentSavard There's also the pairwise recipe which works with any iterable (iterators included).
        – timgeb
        7 mins ago










      • @VincentSavard This doesn't work when reading lines from a file, however.
        – Jack Aidley
        7 mins ago










      • @JackAidley Why wouldn't it work? You can read the first two lines to create the first element, then it's just a matter of reading the file line by line.
        – Vincent Savard
        3 mins ago
















      The example above is, of course, a toy, you can see the motivating example here: stackoverflow.com/questions/53762253/… where the asker wants to search for a particular sequence in one line and print the next.
      – Jack Aidley
      27 mins ago




      The example above is, of course, a toy, you can see the motivating example here: stackoverflow.com/questions/53762253/… where the asker wants to search for a particular sequence in one line and print the next.
      – Jack Aidley
      27 mins ago












      @JackAidley Usually, in cases like these, I believe the pattern to zip the list with itself, offset by one is interesting. For instance, you could do : for previous, current in zip(my_list, my_list[1:]):. This prevents you from doing fancy tricks with next, and is quite readable and elegant.
      – Vincent Savard
      20 mins ago






      @JackAidley Usually, in cases like these, I believe the pattern to zip the list with itself, offset by one is interesting. For instance, you could do : for previous, current in zip(my_list, my_list[1:]):. This prevents you from doing fancy tricks with next, and is quite readable and elegant.
      – Vincent Savard
      20 mins ago














      @VincentSavard There's also the pairwise recipe which works with any iterable (iterators included).
      – timgeb
      7 mins ago




      @VincentSavard There's also the pairwise recipe which works with any iterable (iterators included).
      – timgeb
      7 mins ago












      @VincentSavard This doesn't work when reading lines from a file, however.
      – Jack Aidley
      7 mins ago




      @VincentSavard This doesn't work when reading lines from a file, however.
      – Jack Aidley
      7 mins ago












      @JackAidley Why wouldn't it work? You can read the first two lines to create the first element, then it's just a matter of reading the file line by line.
      – Vincent Savard
      3 mins ago




      @JackAidley Why wouldn't it work? You can read the first two lines to create the first element, then it's just a matter of reading the file line by line.
      – Vincent Savard
      3 mins ago












      up vote
      1
      down vote













      It depends what you mean by 'safe', as others have commented, it is okay, but you can imagine some contrived situations that might catch you out, for example consider this code snippet:



      b = [1,2,3,4,5,6,7]
      a = iter(b)
      def yield_stuff():
      for item in a:
      print(item)
      print(next(a))
      yield 1

      list(yield_stuff())


      On Python <= 3.6 it runs and outputs:



      1
      2
      3
      4
      5
      6
      7


      But on Python 3.7 it raises RuntimeError: generator raised StopIteration. Of course this is expected if you read PEP 479 and if you're thinking about handling StopIteration anyway you might never encounter it, but I guess the use cases for calling next() inside a for loop are rare and there are normally clearer ways of re-factoring the code.






      share|improve this answer

























        up vote
        1
        down vote













        It depends what you mean by 'safe', as others have commented, it is okay, but you can imagine some contrived situations that might catch you out, for example consider this code snippet:



        b = [1,2,3,4,5,6,7]
        a = iter(b)
        def yield_stuff():
        for item in a:
        print(item)
        print(next(a))
        yield 1

        list(yield_stuff())


        On Python <= 3.6 it runs and outputs:



        1
        2
        3
        4
        5
        6
        7


        But on Python 3.7 it raises RuntimeError: generator raised StopIteration. Of course this is expected if you read PEP 479 and if you're thinking about handling StopIteration anyway you might never encounter it, but I guess the use cases for calling next() inside a for loop are rare and there are normally clearer ways of re-factoring the code.






        share|improve this answer























          up vote
          1
          down vote










          up vote
          1
          down vote









          It depends what you mean by 'safe', as others have commented, it is okay, but you can imagine some contrived situations that might catch you out, for example consider this code snippet:



          b = [1,2,3,4,5,6,7]
          a = iter(b)
          def yield_stuff():
          for item in a:
          print(item)
          print(next(a))
          yield 1

          list(yield_stuff())


          On Python <= 3.6 it runs and outputs:



          1
          2
          3
          4
          5
          6
          7


          But on Python 3.7 it raises RuntimeError: generator raised StopIteration. Of course this is expected if you read PEP 479 and if you're thinking about handling StopIteration anyway you might never encounter it, but I guess the use cases for calling next() inside a for loop are rare and there are normally clearer ways of re-factoring the code.






          share|improve this answer












          It depends what you mean by 'safe', as others have commented, it is okay, but you can imagine some contrived situations that might catch you out, for example consider this code snippet:



          b = [1,2,3,4,5,6,7]
          a = iter(b)
          def yield_stuff():
          for item in a:
          print(item)
          print(next(a))
          yield 1

          list(yield_stuff())


          On Python <= 3.6 it runs and outputs:



          1
          2
          3
          4
          5
          6
          7


          But on Python 3.7 it raises RuntimeError: generator raised StopIteration. Of course this is expected if you read PEP 479 and if you're thinking about handling StopIteration anyway you might never encounter it, but I guess the use cases for calling next() inside a for loop are rare and there are normally clearer ways of re-factoring the code.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 1 hour ago









          Chris_Rands

          15.2k53868




          15.2k53868






















              up vote
              1
              down vote













              If you modify you code to see what happens to iterator a:



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

              for x in a :
              print 'x', x
              if (x % 2) == 0 :
              print 'a', next(a)


              You will see the printout:



              x 1
              x 2
              a 3
              x 4
              a 5
              x 6
              a 7


              It means that when you are doing next(a) you are moving forward your iterator. If you need (or will need in the future) to do something else with iterator a, you will have problems. For complete safety use various recipes from itertools module. For example:



              from itertools import tee, izip

              def pairwise(iterable):
              "s -> (s0,s1), (s1,s2), (s2, s3), ..."
              a, b = tee(iterable)
              next(b, None)
              return izip(a, b)

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

              for x, next_x in c:
              if x % 2 == 0:
              print next_x


              Not that here you have full control in any place of the cycle either on current iterator element, or next one.






              share|improve this answer



























                up vote
                1
                down vote













                If you modify you code to see what happens to iterator a:



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

                for x in a :
                print 'x', x
                if (x % 2) == 0 :
                print 'a', next(a)


                You will see the printout:



                x 1
                x 2
                a 3
                x 4
                a 5
                x 6
                a 7


                It means that when you are doing next(a) you are moving forward your iterator. If you need (or will need in the future) to do something else with iterator a, you will have problems. For complete safety use various recipes from itertools module. For example:



                from itertools import tee, izip

                def pairwise(iterable):
                "s -> (s0,s1), (s1,s2), (s2, s3), ..."
                a, b = tee(iterable)
                next(b, None)
                return izip(a, b)

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

                for x, next_x in c:
                if x % 2 == 0:
                print next_x


                Not that here you have full control in any place of the cycle either on current iterator element, or next one.






                share|improve this answer

























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  If you modify you code to see what happens to iterator a:



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

                  for x in a :
                  print 'x', x
                  if (x % 2) == 0 :
                  print 'a', next(a)


                  You will see the printout:



                  x 1
                  x 2
                  a 3
                  x 4
                  a 5
                  x 6
                  a 7


                  It means that when you are doing next(a) you are moving forward your iterator. If you need (or will need in the future) to do something else with iterator a, you will have problems. For complete safety use various recipes from itertools module. For example:



                  from itertools import tee, izip

                  def pairwise(iterable):
                  "s -> (s0,s1), (s1,s2), (s2, s3), ..."
                  a, b = tee(iterable)
                  next(b, None)
                  return izip(a, b)

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

                  for x, next_x in c:
                  if x % 2 == 0:
                  print next_x


                  Not that here you have full control in any place of the cycle either on current iterator element, or next one.






                  share|improve this answer














                  If you modify you code to see what happens to iterator a:



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

                  for x in a :
                  print 'x', x
                  if (x % 2) == 0 :
                  print 'a', next(a)


                  You will see the printout:



                  x 1
                  x 2
                  a 3
                  x 4
                  a 5
                  x 6
                  a 7


                  It means that when you are doing next(a) you are moving forward your iterator. If you need (or will need in the future) to do something else with iterator a, you will have problems. For complete safety use various recipes from itertools module. For example:



                  from itertools import tee, izip

                  def pairwise(iterable):
                  "s -> (s0,s1), (s1,s2), (s2, s3), ..."
                  a, b = tee(iterable)
                  next(b, None)
                  return izip(a, b)

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

                  for x, next_x in c:
                  if x % 2 == 0:
                  print next_x


                  Not that here you have full control in any place of the cycle either on current iterator element, or next one.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 8 mins ago









                  kale

                  967




                  967










                  answered 1 hour ago









                  user2936599

                  213




                  213






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53764256%2fis-is-safe-to-use-next-within-a-for-loop-in-python%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Trompette piccolo

                      Slow SSRS Report in dynamic grouping and multiple parameters

                      Simon Yates (cyclisme)