在 Python 的 for 循环中使用 next 安全吗?

2024-04-16

考虑以下 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 异常不是问题或将被处理),或者对循环内循环的迭代器的修改是否构成违反某些原则?


什么也没有wrong从协议角度或理论上来说,这会阻止您编写此类代码。一个耗尽的迭代器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

Why is 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 recipe https://docs.python.org/3/library/itertools.html#itertools-recipes来自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) 

Demo:

>>> 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 https://pypi.org/project/more-itertools/模块,包括一个实现pairwise https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.pairwise.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Python 的 for 循环中使用 next 安全吗? 的相关文章

  • LibreOffice 并行将 .docx 转换为 .pdf 效果不佳

    我有很多 docx 文件需要转换为 pdf 将它们一一转换需要很长时间 所以我编写了一个 python 脚本来并行转换它们 from subprocess import Popen import time import os os chdi
  • Tkinter 菜单删除项

    如何删除任何菜单项 例如我想删除 播放 self menubar Menu self root self root config menu self menubar self filemenu2 Menu self menubar self
  • 定义Python源代码编码的正确方法

    PEP 263 http www python org dev peps pep 0263 定义如何声明Python源代码编码 通常 Python 文件的前两行应以以下内容开头 usr bin python coding
  • 如何调整 matplotlib 单选按钮的大小和纵横比?

    我已经尝试了几个小时来使简单的单选按钮列表的大小和纵横比正确 但没有成功 首先 导入模块 import matplotlib pyplot as plt from matplotlib widgets import RadioButtons
  • 使用 Python 3 动态插入到 sqlite

    我想使用 sqlite 写入多个表 但我不想提前手动指定查询 有数十种可能的排列 例如 def insert sqlite tablename data list global dbc dbc execute insert into tab
  • 如何获取numpy.random.choice的索引? - Python

    是否可以修改 numpy random choice 函数以使其返回所选元素的索引 基本上 我想创建一个列表并随机选择元素而不进行替换 import numpy as np gt gt gt a 1 4 1 3 3 2 1 4 gt gt
  • 使用 Pytest 的参数化添加测试功能的描述

    当其中一个测试失败时 可以在测试正在测试的内容的参数化中添加描述 快速了解测试失败的原因 有时您不知道测试失败的原因 您必须查看代码 通过每个测试的描述 您就可以知道 例如 pytest mark parametrize num1 num2
  • python 中的 h2o 框架子集

    如何在 python 中对 h2o 框架进行子集化 如果 x 是一个 df 并且 Origin 是一个变量 那么在 pandas 中我们通常可以通过以下方式进行子集化 x x Origin AAF 但使用 h2o 框架会出现以下错误 H2O
  • 在Python中读取tiff标签

    我正在尝试用 Python 读取 tiff 文件的标签 该文件是 RGB 的uint16每个通道的值 我目前正在使用tifffile import tifffile img tifffile imread file tif 然而 img是一
  • 更改QLineEdit的ClearButton图标

    我想在Windows 10 1909 64位 上的Python 3 8和PyQt5 5 15 0 上更改我的QLineEdit的ClearButton图标 稍后我想在Linux上运行代码 我尝试应用此处找到的代码 如何在 QLineEdit
  • Python“非规范化”unicode 组合字符

    我正在寻找标准化 python 中的一些 unicode 文本 我想知道是否有一种简单的方法可以在 python 中获得组合 unicode 字符的 非规范化 形式 例如如果我有序列u o xaf i e latin small lette
  • 使用标签或 href 传递 Django 数据

    我有一个包含链接的表 当单击该链接进行更多操作时 我想将一些数据传递给我的函数 my html table tbody for query in queries tr td value a href internal my func que
  • Python 2 的 `exceptions` 模块在 Python3 中丢失了,它的内容到哪里去了?

    一位朋友提到 对于 Python 2 假设您在命令行上的路径环境变量中有它 pydoc exceptions 非常有用 知道它应该可以为他每周节省几分钟的网络查找时间 我自己每周都会用谷歌搜索一次例外层次结构 所以这对我来说也是一个有用的提
  • 为什么在Python解释器中输入_会返回True? [复制]

    这个问题在这里已经有答案了 我的翻译行为非常奇怪 gt gt gt True gt gt gt type True
  • 检索 geodjango 多边形对象的边界框

    如何在 geodjango 中获取 MultiPolygon 对象的边界框 在 API 中找不到任何内容http geodjango org docs geos html http geodjango org docs geos html
  • 为正则表达式编写解析器

    即使经过多年的编程 我很羞愧地说我从未真正完全掌握正则表达式 一般来说 当问题需要正则表达式时 我通常可以 在一堆引用语法之后 想出一个合适的正则表达式 但我发现自己越来越频繁地使用这种技术 所以 自学并理解正则表达式properly 我决
  • 如何从列表类别中对 pandas 数据框进行排序?

    所以我在下面有这个数据集 我想根据我的列表从 名称 列进行排序 以及按 A 升序和按 B 降序排序 import pandas as pd import numpy as np df1 pd DataFrame from items A 1
  • 确定分割形状几何体的“左”侧和“右”侧

    我的问题是 我怎样才能确定哪一个Aside and Bside的侧面已经分割的旋转矩形几何体 http nbviewer jupyter org urls dl dropbox com s ll3mchnx0jwzjnf determine
  • PyInstaller“ValueError:源代码字符串不能包含空字节”

    我得到了一个ValueError source code string cannot contain null bytes执行命令时pyinstaller main py在具有和不具有管理员权限的cmd中 Traceback most re
  • 根据多个阈值将 SciPy 分层树状图切割成簇

    我想将 SciPy 的树状图切割成多个具有多个阈值的簇 我尝试过使用 fcluster 但它只能削减一个阈值 例如 这是我从另一个问题中摘取的一段代码 import pandas data pandas DataFrame total ru

随机推荐