python - 在 Python 的 for 循环中使用 next 是否安全?
问题描述
考虑以下 Python 代码:
b = [1,2,3,4,5,6,7]
a = iter(b)
for x in a :
if (x % 2) == 0 :
print(next(a))
将打印 3、5 和 7。是在next
可靠构造上迭代的变量上使用 (您可能假设 StopIteration 异常不是问题或将被处理),还是迭代器的修改被循环over inside loop 是否构成违反某些原则?
解决方案
在协议方面或理论上没有任何问题会阻止您编写此类代码。一个用尽的迭代器it
将抛出StopIteration
对 的每个后续调用it.__next__
,因此从技术上讲,如果您在循环体中使用/调用来用尽迭代器,则该for
循环不会介意。next
__next__
我建议不要编写这样的代码,因为该程序将很难推理。如果场景变得比你在这里展示的更复杂一点,至少我必须用笔和纸完成一些输入并弄清楚发生了什么。
实际上,假设您要打印前面有偶数的每个数字,您的代码片段甚至可能不像您认为的那样。
>>> b = [1, 2, 4, 7, 8]
>>> a = iter(b)
>>> for x in a:
...: if x%2 == 0:
...: print(next(a, 'stop'))
4
stop
7
尽管前面有偶数,为什么会被跳过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
结果x = 4
是循环从未分配过,for
因为在循环有机会再次查看next
迭代器之前,显式调用从迭代器中弹出了该元素。for
那是我在阅读代码时讨厌弄清楚细节的事情。
(element, next_element)
如果您想以“ ”对迭代可迭代(包括迭代器) ,请使用文档中的pairwise
配方。itertools
from itertools import tee
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return zip(a, b)
演示:
>>> b = [1,2,3,4,5,6,7]
>>> a = iter(b)
>>>
>>> for x, nxt in pairwise(a): # pairwise(b) also works
...: print(x, nxt)
1 2
2 3
3 4
4 5
5 6
6 7
一般来说,itertools
连同它的配方一起,为编写可读的迭代相关代码提供了许多强大的抽象。在模块中可以找到更多有用的助手more_itertools
,包括pairwise
.
推荐阅读
- string - 如何将字符串转换为双精度,以保持字符串中表示的数字完全相同
- django - 使用 drf-nested-routers 找不到页面错误
- android - Android X onMenuItemSelected
- javascript - 尝试动态更改导航栏中的“活动”类 - Node.js/Express/Handlebars
- java - 在 Java 中使用 WEKA
- javascript - 路由导航方法未重定向到目标组件
- node.js - expressjs 是否能够同时为多个用户提供文件?
- angular - angular4 Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays
- javascript - 在不提供输入的情况下调用迭代器函数会产生奇怪的行为?
- c# - 在 Post 请求中发送 DateTime