Is is safe to use next within a for loop in Python?
up vote
9
down vote
favorite
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
add a comment |
up vote
9
down vote
favorite
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
A question to ponder: what happens if you skip theif
condition and always callnext(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
add a comment |
up vote
9
down vote
favorite
up vote
9
down vote
favorite
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
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
python
asked 2 hours ago
Jack Aidley
11.3k42858
11.3k42858
A question to ponder: what happens if you skip theif
condition and always callnext(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
add a comment |
A question to ponder: what happens if you skip theif
condition and always callnext(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
add a comment |
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.
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 tozip
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 withnext
, and is quite readable and elegant.
– Vincent Savard
20 mins ago
@VincentSavard There's also thepairwise
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
|
show 2 more comments
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.
add a comment |
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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.
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 tozip
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 withnext
, and is quite readable and elegant.
– Vincent Savard
20 mins ago
@VincentSavard There's also thepairwise
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
|
show 2 more comments
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.
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 tozip
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 withnext
, and is quite readable and elegant.
– Vincent Savard
20 mins ago
@VincentSavard There's also thepairwise
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
|
show 2 more comments
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.
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.
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 tozip
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 withnext
, and is quite readable and elegant.
– Vincent Savard
20 mins ago
@VincentSavard There's also thepairwise
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
|
show 2 more comments
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 tozip
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 withnext
, and is quite readable and elegant.
– Vincent Savard
20 mins ago
@VincentSavard There's also thepairwise
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
|
show 2 more comments
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.
add a comment |
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.
add a comment |
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.
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.
answered 1 hour ago
Chris_Rands
15.2k53868
15.2k53868
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
edited 8 mins ago
kale
967
967
answered 1 hour ago
user2936599
213
213
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
A question to ponder: what happens if you skip the
if
condition and always callnext(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