Python迭代器是否没有hasNext方法?

相关:我如何知道一开始发电机是否为空?

使用next(iterator, default_value)可以替代StopIteration。

例如:

>>> a = iter('hi')

>>> print next(a, None)

h

>>> print next(a, None)

i

>>> print next(a, None)

None

因此,如果您不想使用异常方法,则可以检测到None或迭代器末尾的其他预先指定的值。

如果将"无"用作"前哨",则最好确保迭代器没有任何"无"。您还可以执行sentinel = object()和next(iterator, sentinel)并使用is进行测试。

在@samboosalis之后,我宁愿使用内置的unittest.mock.sentinel对象,该对象允许您先编写显式的next(a, sentinel.END_OF_ITERATION),然后编写if next(...) == sentinel.END_OF_ITERATION

这比例外还漂亮

不,没有这样的方法。迭代结束由异常指示。请参阅文档。

"请求宽恕比允许容易。"

"请求宽容比允许要容易。":检查迭代器是否具有下一个元素并不要求允许。在某些情况下,您想测试下一个元素的存在而不消耗它。如果有unnext()方法可以通过调用next()检查第一个元素是否存在,那么我将接受尝试捕获解决方案。

@Giorgio,如果不执行另一个生成元素的代码,就无法知道另一个元素是否存在(您不知道生成器是否将执行yield)。当然,编写存储next()结果并提供has_next()和move_next()的适配器并不难。

可以使用相同的思想来实现hasNext()方法(在成功时产生,缓存并返回true,或者在失败时返回false)。然后hasNext()和next()都将依赖于通用的基础getNext()方法和缓存项。如果真的很容易实现提供它的适配器,我真的不明白为什么next()不应该出现在标准库中。

@乔治,我不明白你在说什么。 next是标准;它抛出序列的末尾。适配器可以使用此next并缓存该值。没有人说它不应该在标准库中。我猜只是没有需求。

我了解,我认为不将其纳入标准的动机是技术上的。正如您所说,可能对它的需求根本不够。

@Giorgio,我大体上同意你的观点,尽管:如果hasNext()在标准库中,则所有迭代器都将被强制实现(或者如果不支持它,则返回错误……在那里进行设计决策)。对于某些迭代器而言,这些迭代器对时间的上下文高度敏感,因此迭代器中第一项的值可以在对hasNext()的调用与对next()的调用之间(可能在不同的模块中)改变,结果next()返回一个过时的值。我不知道,只是想看看争论的双方。我同意这样做会有帮助。

@LarsH:您的意思是例如从文件读取的迭代器可以在读取文件时更改?我同意这可能是一个问题(这会影响提供next()和hasNext()方法的任何库,而不仅仅是一个假设的Python库)。所以是的,如果要扫描的流的内容取决于何时读取元素,则next()和hasNext()会变得很棘手。

@Giorgio:是的,这就是我在想的一个例子。因此,当Python glob库的iglob()返回一个迭代器时,我们会遇到这个问题:一个迭代器,其返回值对时间敏感(即不是纯函数)。那么这是否意味着不应将诸如I / O之类的不纯函数作为迭代器使用?设计决策...

您都可以通过两种方式寻求许可。这不是C;)我想没有has_next(),因为它会使事情变得复杂。

python通常缺乏基本语言用法的结构,这些结构迫使诸如捕获异常之类的事情发生。然后,它或多或少地被认为是正确的做事方式而变得合理。另一个是缺少do .. while

如果您确实需要has-next功能(例如,因为您只是忠实地从Java的参考实现中转录算法,或者是因为您正在编写原型,则需要在完成后轻松将其转录为Java),只需使用一些包装器类就可以轻松获得它。例如:

class hn_wrapper(object):

def __init__(self, it):

self.it = iter(it)

self._hasnext = None

def __iter__(self): return self

def next(self):

if self._hasnext:

result = self._thenext

else:

result = next(self.it)

self._hasnext = None

return result

def hasnext(self):

if self._hasnext is None:

try: self._thenext = next(self.it)

except StopIteration: self._hasnext = False

else: self._hasnext = True

return self._hasnext

现在像

x = hn_wrapper('ciao')

while x.hasnext(): print next(x)

发出

c

i

a

o

按要求。

请注意,使用next(sel.it)作为内置函数需要Python 2.6或更高版本;如果您使用的是旧版本的Python,请改为使用self.it.next()(在示例用法中对于next(x)类似)。 [[[您可能会合理地认为此注释是多余的,因为Python 2.6已经存在一年多了-但是当我在响应中使用Python 2.6功能时,很多评论者或其他人有责任指出它们是2.6功能,因此,我尝试一次阻止此类评论;-)]]

"忠实地从Java参考实现中转录算法"是需要has_next方法的最糟糕原因。 Python的设计使得不可能使用filter来检查数组是否包含与给定谓词匹配的元素。 Python社区的傲慢和短视令人震惊。

很好的答案,我将其复制为说明从Java代码中获取的某些设计模式

我使用Python3,这段代码给了我TypeError: iter() returned non-iterator

@JonathanCast不确定我是否遵循。在Python中,通常使用map和any而不是filter,但是可以使用SENTINEL = object(); next(filter(predicate, arr), SENTINEL) is not SENTINEL或忘记SENTINEL而只使用try: except并捕获StopIteration。

除了提到StopIteration之外,Python的" for"循环还可以满足您的要求:

>>> it = iter("hello")

>>> for i in it:

...     print i

...

h

e

l

l

o

从任何迭代器对象尝试__length_hint __()方法:

iter(...).__length_hint__() > 0

我一直想知道为什么python拥有所有这些__ xxx __方法?他们看起来很丑。

正当问题!通常,它是内置函数公开的方法的语法(例如len,实际上是在调用len)。对于length_hint不存在这样的内置函数,但实际上它是一个挂起的建议(PEP424)。

@mP。这些功能在那里,因为有时需要它们。它们故意是丑陋的,因为它们被认为是不得已的方法:如果使用它们,您将知道自己做的是非Python的并且有潜在危险的操作(该操作可能随时停止工作)。

像__init__和__main__一样?恕我直言,无论您试图为其辩护,都有些混乱。

hasNext在某种程度上转换为StopIteration异常,例如:

>>> it = iter("hello")

>>> it.next()

'h'

>>> it.next()

'e'

>>> it.next()

'l'

>>> it.next()

'l'

>>> it.next()

'o'

>>> it.next()

Traceback (most recent call last):

File"", line 1, in

StopIteration

StopIteration文档:http://docs.python.org/library/exceptions.html#exceptions.StopIteration

关于python中的迭代器和生成器的一些文章:http://www.ibm.com/developerworks/library/l-pycon.html

您可以使用itertools.tee tee迭代器,并在teed迭代器上检查StopIteration。

否。最相似的概念很可能是StopIteration异常。

哪些Python将异常用于控制流?听起来不错。

正确:应该使用异常来处理错误,而不是定义正常的控制流程。

我相信python只是具有next(),根据文档,它抛出一个异常是没有更多的元素。

http://docs.python.org/library/stdtypes.html#iterator-types

以下是促使我进行搜索的用例:

def setfrom(self,f):

"""Set from iterable f"""

fi = iter(f)

for i in range(self.n):

try:

x = next(fi)

except StopIteration:

fi = iter(f)

x = next(fi)

self.a[i] = x

在hasnext()可用的地方,一个可以做

def setfrom(self,f):

"""Set from iterable f"""

fi = iter(f)

for i in range(self.n):

if not hasnext(fi):

fi = iter(f) # restart

self.a[i] = next(fi)

对我来说更干净显然,您可以通过定义实用程序类来解决问题,但是随后发生的事情是,您有二十多种不同的,几乎等同的解决方法,每个方法都有其怪癖,并且,如果您想重用使用不同解决方法的代码,则必须在您的单个应用程序中具有多个几乎相等的值,或者四处浏览并重写代码以使用相同的方法。"一次做就做好"的格言非常失败。

此外,迭代器本身需要进行内部" hasnext"检查,以查看是否需要引发异常。然后隐藏此内部检查,以便需要通过尝试获取项目,捕获异常并在抛出异常时运行处理程序来对其进行测试。这是不必要的隐藏IMO。

对于此用例,可以使用itertools.cycle

建议的方法是StopIteration。

请从tutorialspoint看斐波那契示例

#!usr/bin/python3

import sys

def fibonacci(n): #generator function

a, b, counter = 0, 1, 0

while True:

if (counter > n):

return

yield a

a, b = b, a + b

counter += 1

f = fibonacci(5) #f is iterator object

while True:

try:

print (next(f), end="")

except StopIteration:

sys.exit()

解决此类问题的好方法是检查dir(object / method / iterator / type / class / ...)中的内容

您会看到dir(iterator)返回__length_hint__

iterator.__length_hint__()为正,直到迭代结束。

而已。

不能保证__length_hint__是准确的:python.org/dev/peps/pep-0424。

我解决问题的方法是保持到目前为止迭代对象的数量。我想使用对实例方法的调用来遍历一个集合。由于我知道集合的长度以及到目前为止已计算的项目数,因此有效地使用了hasNext方法。

我的代码的简单版本:

class Iterator:

# s is a string, say

def __init__(self, s):

self.s = set(list(s))

self.done = False

self.iter = iter(s)

self.charCount = 0

def next(self):

if self.done:

return None

self.char = next(self.iter)

self.charCount += 1

self.done = (self.charCount < len(self.s))

return self.char

def hasMore(self):

return not self.done

当然,示例是一个玩具,但是您知道了。在无法获取迭代器长度的情况下(例如生成器等),这将不起作用。

java 迭代器的hasnext,在Python迭代器中具有hasNext?相关推荐

  1. python迭代器使用_python迭代器的使用方法实例

    什么是迭代器?迭代器是带有next方法的简单对象,当然也要实现__iter__函数.迭代器能在一序列的值上进行迭代,当没有可供迭代时,next方法就会引发StopIteration 的异常.pytho ...

  2. Python迭代器实现

    欢迎访问我的个人博客 https://vincillau.github.io/ 文章目录 欢迎访问我的个人博客 https://vincillau.github.io/ Python迭代器实现 引言 ...

  3. java中迭代器要导包吗_java 中迭代器的使用方法详解

    java 中迭代器的使用方法详解 前言: 迭代器模式将一个集合给封装起来,主要是为用户提供了一种遍历其内部元素的方式.迭代器模式有两个优点:①提供给用户一个遍历的方式,而没有暴露其内部实现细节:②把元 ...

  4. Java 方法使用总结(重载、数组输出、enum和switch、foreach和迭代器、可变长度参数、重载中使用可变长度参数)

    方法重载 方法名相同 方法的参数类型,参数个不一样 方法的返回类型可以不相同 方法的修饰符可以不相同 main 方法也可以被重载 class MyClass {int height;MyClass() ...

  5. python迭代器两个基本方法可供参考_2018.8.10 python中的迭代器

    主要内容: 1.函数名的使用 2.闭包 3.迭代器 一.函数名的运用 函数名是一个变量,但他是一个特殊的变量,与括号配合可执行函数的变量. 1.函数名的内存地址 def func(): print(' ...

  6. python迭代器和生成器_python中迭代器和生成器。

    前言:很多python教程中,对python的解释不容易理解,本文记录自己的理解和体会,是对迭代器和生成器的初步理解. 迭代器: 迭代器的实质是实现了next()方法的对象,常见的元组.列表.字典都是 ...

  7. python迭代器好处_关于Python中迭代器的作用

    迭代器的定义:含有__iter__()方法和__next__()方法的就是迭代器,即(iterate) 含有__iter__()方法就可以使用for循环,即iterable(可迭代的) Iterabl ...

  8. python中迭代器有哪些_Python迭代器:什么是Python中的迭代器以及如何使用它?

    Python编程语言已经扩展了创新的每一个方面,包括机器学习.数据科学.人工智能等,这些概念是Python作为编程语言取得成功的基石.在本文中,我们将通过以下概念来理解Pytho Python编程语言 ...

  9. python 迭代器协议_浅谈Python中的生成器和迭代器

    迭代器 迭代器协议 对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么返回一个异常来终止本次迭代.(只能往前走,不能往后退!) 迭代器对象 遵循了(实现了)迭代器协议的对象.(对象内 ...

最新文章

  1. bootstrap的使用
  2. 使用驱动器f:中的光盘之前需要将其格式化_mac虚拟光驱Daemon Tools高级功能详解—光盘刻录...
  3. 【PHP ThinkPHP框架】小bug汇总[更新]
  4. 含根式的定积分计算_不定积分计算法则总结
  5. OverFeat4.2的安装和使用
  6. 太快了,太变态了:什么会影响Java中的方法调用性能?
  7. 【离散数学】集合的包含排斥原理
  8. ubuntu 中怎么安装 jdk 7
  9. 如何向某网址Post信息,并得到CookieContainer以便以后直接通过验证
  10. Robust Representation Learning with Feedback for Single Image Deraining论文解读
  11. 计算机程序如何计算除法,在EXCEL表格公式中怎样计算乘积及除法?
  12. 自主招生计算机网测考什么,自主招生是什么意思 2019自主招生考试考什么
  13. scroll-view
  14. 「快学springboot」SpringBoot多环境配置文件
  15. php 歌词同步,HTML5实践之歌词同步播放器的示例代码分享
  16. 解析button和input type=button 的区别
  17. matlab神经网络函数(feedforwardnet,fitnet,patternet)
  18. 直播APP开发技术原理分享
  19. 软考必考之有关计算机的知识产权基础
  20. 杀毒软件的Linux版,Linux杀毒软件免费版下载

热门文章

  1. python按行拆分表格_Python将单元格中的多个值拆分为多行
  2. 信号量哲学家问题java_利用AND信号量机制解决哲学家进餐问题
  3. ftp文件传输(适用于两台通过网线直连的电脑)
  4. PLSQL开发笔记和小结
  5. fpga的EPCS 配置的2种方法(图文讲解,哈哈,网上互相抄袭的一些文字说明太不明了了)
  6. latex 学习使用记录(插图片,插表格,插公式,插参考文献)
  7. hiho 1051 : 补提交卡
  8. 金蝶标准单据扩展类开发
  9. 计算机硬件仿真软件,仿真软件
  10. 面经—CV秋招40万+offer上岸经验:分享100道CV最新面试题