python迭代器详解,python语言编程中迭代器

  python迭代器详解,python语言编程中迭代器

  Yyds干货库存

  你还记得你上次丢东西是什么时候吗?

  你可能会翻遍你的房子。一个房间一个房间的搜,而周围的人问一些没有意义的问题,比如“你上次放在哪里了?”说真的,如果我知道,我就不会给他们打电话了!)如果你优化了你的搜索方式,那就好办了,但是你的房子和房间没有排序……或者说特别有条理。如果你和我一样,被线性搜索困住了。

  在编程中,就像在现实生活中一样,我们通常得不到任何有意义的序列数据。它通常以一片混乱开始,我们必须在它上面执行任务。搜索无序数据可能是第一个想到的例子,但您可能还想做数百件其他事情:将所有华氏温度记录转换为摄氏温度,找到所有数据点的平均值,等等。

  “没错,回收就是为了这个!”

  但这是Python。它的周期在完全不同的层面上。它们很容易使用。

  让我们扔掉那些无聊的东西,好吗?

  像大多数语言一样,Python中有两个基本循环:while和for。

  While while循环非常基础。

  线索=无

  而线索是没有:

  clue=searchLocation()

  在这种情况下,只要循环条件的评估结果为真,就会执行循环代码。

  在Python中,我们还有几个有用的关键字:break立即停止循环,而continue跳转到循环的下一次迭代。

  break最有用的一个方面是,如果我们希望运行相同的代码,直到用户提供有效的输入。

  虽然正确:

  尝试:

  age=int(input(输入您的年龄: ))

  除了值错误:

  请输入一个有效的整数!)

  否则:

  如果年龄为0:

  破裂

  一旦遇到break语句,我们就退出循环。当然,以上是比较复杂的例子,但证明了这一点。你也经常看到while True:用在游戏循环中。

  注意:如果你曾经在任何语言中使用过循环,那么你已经对无限循环(无限循环)很熟悉了。这通常是由于while条件评估为True,并且循环中没有break语句。

  For来自Java、C或许多类似的ALGOL风格的语言。你可能对三路for循环比较熟悉:for I:=1;i 100我:=i 1 .我不知道你怎么样,但是我第一次遇到这种情况的时候,把我吓坏了。我现在很满意,但是没有Python的优雅简洁。

  Python的for循环看起来很不一样。与上述伪代码等价的Python代码是.

  对于在幅度内的I(1,100):

  打印(一)

  Range()是Python中一个特殊的“函数”,它返回一个序列。(技术上来说,根本不是函数。)

  这就是Python ——让人印象深刻的地方。它迭代一种特殊类型的序列,称为iterable,我们将在后面讨论。

  目前最容易理解的是,我们可以迭代一个顺序数据结构,比如数组(Python中称为“list”)。

  因此,我们可以这样做。

  places=[纳什维尔,挪威,博内尔,津巴布韦,芝加哥,捷克斯洛伐克]

  对于地点中的地点:

  打印(地点)

  打印(.“回来!”)

  我们明白了。

  纳什维尔

  挪威

  博奈尔岛

  津巴布韦

  芝加哥

  捷克斯洛伐克

  .又回来了!

  为.elsePython的循环中还有另一个独特的技巧:else子句!循环完成后,else将在没有break语句的情况下运行。但是,如果手动中断循环,它将完全跳过else。

  places=[纳什维尔,挪威,博内尔,津巴布韦,芝加哥,捷克斯洛伐克]

  恶棍_at=马里

  对于地点中的地点:

  if place==恶棍_at:

  打印(恶棍被捕!)

  破裂

  否则:

  打印(恶棍又跑了。)

  由于“马里”不在列表中,我们看到了“恶棍又跑了”的消息。但是,如果我们把反派_at的值改成挪威,就会看到“反派被俘!”而看不到“反派又跑了。”。

  有do吗.怀尔。没有Python做的.while循环。如果您正在寻找这样的循环,典型的Python使用while True:with internal break condition,正如我们之前演示的那样。

  数据(容器)Python有许多容器或数据结构来保存数据。我们不会深入讨论其中任何一个,但我想快速浏览一下最重要的部分:

  list列出一个变量序列(实际上是一个数组)。

  它由方括号[]定义,您可以通过索引访问它的元素。

  foo=[2,4,2,3]

  print(foo[1])

  四

  foo[1]=42

  打印

  [2, 42, 2, 3]

  虽然对它没有严格的技术要求,但是典型的惯例是列表只包含相同类型的元素(“同质”)。

  Tupletuple是不可变的序列。一旦你定义了它,你就不能在技术上改变它(回想一下之前不变性的含义)。这意味着在定义了一个元组之后,就不能在元组中添加或删除元素了。

  元组在括号()中定义,可以通过索引访问它的元素。

  foo=(2,4,2,3)

  print(foo[1])

  四

  foo[1]=42

  type error:“tuple”对象不支持项分配

  与列表不同,标准约定允许元组包含不同类型的元素(“异类”)。

  Setset是一个无序的变量集,它保证没有重复。记住“无序”很重要:不能保证单个元素的顺序!

  集合是用花括号{}定义的,但是如果你想要一个空集,你可以用foo=set()或者foo={}来创建一个空字典。你不能通过索引访问它的元素,因为它是无序的。

  foo={2,4,2,3}

  打印

  {2, 3, 4}

  print(foo[1])

  类型错误:“set”对象不支持索引

  对于要添加到集合中的对象,它也必须是hash。如果满足以下条件,则对象是可哈希的:

  它定义了方法__hash__(),该方法将哈希值(hash)作为整数返回。(见下文)它定义了__eq__()如何比较两个对象。对于同一个对象(值),一个有效的哈希值(hash)应该总是相同的,并且应该是合理唯一的,所以另一个对象返回相同的hash并不常见。(两个或两个以上具有相同哈希值的对象称为哈希冲突,并且仍然会发生。)

  Dictdict(字典)是一种键值数据结构。

  它在花括号中定义了{}:用于分隔键和值。它是无序的,所以你不能通过索引访问它的元素;但是您可以通过[]添加键值来访问元素。

  foo={a : 1, b : 2, c : 3, d : 4}

  print(foo[b])

  2

  foo[b]=42

  打印

  {a: 1, b: 42, c: 3, d: 4}

  只有可哈希的对象可以用作字典键。(关于set hashing的更多信息,请参见官网部分。)

  除了这些基础,Python还提供了额外的容器/数据结构。您可以在内置模块集合中找到它们。

  解包有一个重要的Python语法,我们还没有讨论,但它很快就会派上用场。我们可以将容器中的每个元素赋给一个变量!这叫拆包。

  当然,我们需要确切地知道需要解包多少才能完成,否则我们将得到一个ValueError异常。

  让我们看一个使用元组的基本例子。

  全名=(卡门,桑迪戈)

  名字,姓氏=全名

  打印(第一页)

  卡门

  打印(最后)

  圣地牙哥

  查看第二行代码,我们可以列出多个要赋值的变量,用逗号分隔。Python会将容器拆分到等号的右边,并按照从左到右的顺序将每个值赋给一个变量。

  注意:记住,集合是无序的!尽管从技术上来说,您可以使用集合来实现这一点,但是您无法确定将什么值赋给什么变量。保证分布不按顺序,集合的值的分布顺序通常是偶然的!

  InPython在中提供了一个关键字,用于检查是否在容器中找到了特定的元素。

  places=[纳什维尔,挪威,博内尔,津巴布韦,芝加哥,捷克斯洛伐克]

  如果“纳什维尔”在某些地方:

  打印(音乐城!)

  这适用于许多容器,包括列表、元组、集甚至字典键(但不包括字典值)。

  如果您希望您的自定义类之一支持in运算符,您只需定义__contains__(self,item)方法,该方法应返回True或False。

  迭代器Python的循环与我前面提到的迭代器结合使用。前面提到的数据结构都是可以被迭代器迭代的对象。

  好吧,我们从头说起。Python容器对象(如list)也是可迭代对象,因为它的__iter__()方法返回迭代器对象。

  方法__next__()也是一个迭代器,它在容器迭代器的情况下返回下一项。即使是无序的容器,比如set(),也可以被迭代器遍历。

  当__next__()不能返回任何其他内容时,它会抛出一个名为StopIteration的特殊异常。这可以用试试.除了捕捉异常。

  例如,让我们再来看看遍历列表的循环.

  档案=[伯爵夫人,双重麻烦,地球蛮, Kneemoi ,帕蒂盗窃罪, RoboCrook ,莎拉纳德,顶级垃圾,维克滑头,神奇鼠]

  对于档案中的骗子:

  打印(弯曲)

  档案是一个列表对象,这是一个迭代对象。当Python到达for循环时,它会做三件事:

  调用iter(档案)并执行档案。__iter__()依次。这将返回一个迭代器对象list_iter,我们将调用它。这个迭代器对象将被回收。对于循环的每次迭代,它调用next (list _ iterator),执行list _ iterator。_ _ next _ _()并将返回值赋给crook。如果迭代器抛出一个特殊的异常StopIteration,循环结束并退出。虽然正确:如果我在一个循环中重写逻辑,可能会更容易理解。

  list_iter=iter(档案)

  虽然正确:

  尝试:

  crook=next(list_iter)

  打印(弯曲)

  除了StopIteration:

  破裂

  如果你尝试这两个循环,你会发现它们做的完全一样!

  在理解__iter__()、__next__()和StopIteration异常是如何工作的之后,现在可以让自己的类迭代了!

  注意:虽然你可以从迭代器类中单独定义迭代器类,但是你不一定要这样做!只要在类中定义了这两个方法,并且__next__()行为正常,就可以将__iter__()定义为return self。

  值得注意的是,迭代器本身是迭代的:它们有一个__iter__()方法返回self。

  字典案例假设我们有一本想要使用的字典。

  位置={

  阅兵场:无,

  Ste。-凯瑟琳街:无,

  维多利亚桥:没有,

  地下城:无,

  “皇家公园山”:无,

  美术馆:无,

  “幽默名人堂”:“通缉令”,

  拉钦运河:战利品,

  蒙特利尔爵士音乐节:无,

  奥林匹克体育场:无,

  《圣劳伦斯河》:《溪边》,

  “旧蒙特利尔”:无,

  “麦吉尔大学”:无,

  “木屋了望”:无,

  圣母院:没有

  }

  如果我们只想查看其中的每一项,我们只需要使用for循环。所以,这应该是可行的,对吧?

  对于位置中的位置:

  打印(位置)

  哦亲爱的!这只向我们展示了关键,而不是价值。这不是我们想要的,是吗?

  迪克特。__iter__()返回一个dict_keyiterator对象,该对象执行其类名的操作:它遍历键,但不遍历值。

  为了同时获得键和值,我们需要调用locations.items()来返回dict_items对象。Dict_items.iter()返回dict_itemiterator,它将字典中的每个键值对作为一个元组返回。

  旧版本说明:如果你用的是Python 2,应该改为调用locations.iteritems()。

  还记得刚才我们谈到拆包吗?我们将每个键值对视为一个元组,并将其分成两个变量。

  对于键,locations.items()中的值:

  print(f“{ key }={ value }”)

  打印出以下内容:

  阅兵场=无

  Ste。-凯瑟琳街=无

  维多利亚桥=无

  地下城=无

  皇家公园山=无

  美术馆=无

  幽默名人堂=搜查令

  拉钦运河=战利品

  蒙特利尔爵士音乐节=无

  奥林匹克体育场=无

  圣劳伦斯河=溪边

  旧蒙特利尔=无

  麦吉尔大学=无

  木屋了望台=无

  圣母院=无

  现在我们可以处理数据了。例如,我想在另一本字典中记录重要信息。

  信息={}

  对于location,结果为locations.items():

  如果结果不是无:

  信息[结果]=位置

  #赢得比赛!

  打印(信息[战利品])

  打印(信息[搜查令])

  打印(信息[骗子])

  打印(“维克的滑头.“在jaaaaaaaaail!”)

  这将找到战利品,权证和骗子,并列出他们在正确的顺序:

  拉钦运河

  幽默名人堂

  圣劳伦斯河

  滑头维克.在jaaaaaaaaail!

  自定义迭代器我之前提到过你可以自己做迭代器和迭代器,但是现在让我们来实现它!

  假设我们想要方便地保存一个代理列表,这样我们就可以通过它们的编号来识别它们。然而,有一些代理我们不能谈论。我们可以通过将代理ID和名称存储在字典中,然后维护一个分类代理列表来轻松实现这一点。

  注意:请记住,在我们对类的讨论中,Python中实际上没有私有变量这种东西。如果你真的想保密,请使用行业标准的加密和安全措施,或者至少不要将你的API暴露给任何恶意的操作者。)

  对于初学者来说,这是这个类的基本结构:

  班级代理花名册:

  def __init__(self):

  自我。_agents={}

  自我。_classified=[]

  def add_agent(自身,名称,编号,已分类=False):

  自我。_agents[number]=name

  如果分类:

  自我。_classified.append(名称)

  def validate_number(self,number):

  尝试:

  名字=自我。_代理人[数量]

  除了KeyError:

  返回False

  否则:

  返回True

  定义查找_代理人(自身,编号):

  尝试:

  名字=自我。_代理人[数量]

  除了KeyError:

  name=未知代理

  否则:

  如果名字在自己身上。_分类:

  name=分类

  返回名称

  我们可以继续测试,只是为了后续:

  花名册=代理花名册()

  花名册. add_agent(安蒂克威,2539634)

  花名册. add_agent(伊凡点子,1324595)

  花名册. add_agent(坚如磐石,1385723)

  花名册. add_agent(Chase Devineaux ,1495263,True)

  打印(花名册.验证号码(2539634))

  真实的

  打印(花名册.验证号码(9583253))

  错误的

  打印(花名册. lookup_agent(1324595))

  伊凡的主意

  打印(花名册. lookup_agent(9583253))

  未知代理

  打印(花名册. lookup_agent(1495263))

  分类的

  太好了,这完全符合预期!现在,如果我们希望能够遍历整个字典。

  但是,我们不想直接访问花名册。_agents字典,因为这将忽略该类的整个“分类”方面。我们该如何处理?

  正如我之前提到的,我们可以让这个类充当自己的迭代器,这意味着它有一个__next__()方法。在这种情况下,我们只会回归自我。然而,这里有一个超级简单的Python教程,所以让我们跳过烦人的步骤,简化内容,实际上创建一个单独的迭代器类。

  在这个例子中,我实际上把字典变成了元组列表,这将允许我使用索引。记住,字典是无序的。)我也会算算有多少特工未分类。当然,所有这些逻辑都属于这个__init__()方法:

  类代理名册_迭代器:

  def __init__(自身,容器):

  自我。_花名册=列表(容器。_ agents.items())

  自我。_ classified=容器。_机密

  自我。_max=len(self。_花名册)- len(self。_分类)

  自我。_index=0

  要成为迭代器,类必须有__next__()方法;这是唯一的要求!记住,一旦我们没有更多的数据要返回,这个方法需要抛出一个StopException异常。

  我将AgentRoster_Iterator的__next__()方法定义如下:

  类代理名册_迭代器:

  # .剪.

  def __next__(自己):

  如果自我。_index==self。_max:

  提升停止迭代

  否则:

  r=自我。_花名册[self。_index]

  自我。_index=1

  返回r

  现在我们回到AgentRoster类,在这里我们需要添加__iter__()的方法来返回迭代器对象。

  班级代理花名册:

  # .剪.

  def __iter__(self):

  返回agent花名册_迭代器(self)

  这只需要一点点操作,现在我们的AgentRoster类的行为完全符合循环的预期!这段代码如下.

  花名册=代理花名册()

  花名册. add_agent(安蒂克威,2539634)

  花名册. add_agent(伊凡点子,1324595)

  花名册. add_agent(坚如磐石,1385723)

  花名册. add_agent(Chase Devineaux ,1495263,True)

  对于编号,花名册中的名称:

  打印(f { name },id #{number} )

  结果如下.

  安蒂克威,身份证号2539634

  伊凡创意,id号1324595

  坚如磐石,id号1385723

  一直期待我听到后面的皮托尼斯塔:“等等,等等,我们还不能完成它!你连列表解析都没接触过!”

  Python确实为循环和迭代器增加了一个额外的层次,它使用了一个叫做generator的特殊工具。这种类型的类提供了另一个不可思议的工具,称为理解,它就像一个创建数据结构的完美闭环。

  我还故意跳过了zip()和enumerate()的优点,让循环和迭代更加强大。我就在这里总结一下,但不希望文章太长。这些我后面也会讲。

  我猜你们中的一些人已经在期待了,但是不幸的是,你将不得不等到下一篇文章来了解更多。

  总结让我们回顾一下本节中最重要的概念:

  只要while的计算结果为,循环将运行True。你可以使用关键字跳出循环断点,或者使用关键字跳到下一个迭代继续。for循环遍历一个可迭代的对象(可以被迭代的对象),比如一个列表。range()函数返回一个迭代的数字序列,可以在for循环中使用,例如对于range(1,100)中的I。Python没有do.while循环。使用while True:带有显式break语句的循环。Python有四种基本的数据结构或容器:列表是一种可变的、有序的、顺序的结构……基本上是一个数组。元组是不可变的、有序的和顺序的结构。想想清单,但不能修改内容。集合是一个可变的无序结构,保证不会有重复的元素。它们只能存储散列对象。字典是一种可变的无序结构,用于存储键值对。你通过关键字而不是索引来查找条目。只有可哈希的对象可以用作键。你可以用约定把一个容器的值拆分成多个变量a,b,c=someContainer。左侧容器中变量的数量和右侧容器中元素的数量必须相同!您可以使用关键字快速检查元素是否在容器中。如果您希望您的类支持这一点,请定义contains()方法。Python的容器是可迭代对象的例子:它们返回可以遍历其内容的迭代器。迭代对象总是通过iter iterator()方法返回一个iterator对象。迭代器对象总是有一个返回一个值的方法next()。容器迭代器的next()方法将返回容器中的下一个元素。当没有更多的东西要返回时,迭代器抛出一个StopIteration异常。原创作品来自程,

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • python语言基本语句用法总结大全,python语言基本语句用法总结怎么写
  • python语言基本语句用法总结大全,python语言基本语句用法总结怎么写,python语言基本语句用法总结
  • python是一种什么类型的计算机语言,python语言是一种什么类型的编程语言
  • Python的保留字符,python语言中的保留字
  • python的指数e怎么表示,指数函数在python语言中怎么表示
  • python语言合法的变量命名,在python中变量的命名要注意哪些问题
  • python变量命名可以用中文吗,下面哪一个不是python语言合法的变量命名
  • Python分词库,用python语言中文分词第三方库jieba对文件data
  • python中复数类型的实部和虚部都是浮点数,python语言中,复数类型中实数部分和虚数部分
  • 用python语言判断一个数是否为素数,Python判断是不是素数
  • python语句变量命名规则,python语言命名变量规则
  • 简述python语言程序的特点,以下关于python语言技术特点
  • matlab中for循环的用法例子,python语言for循环语句
  • Python主网站,python语言的官方网站
  • 用python开发的软件有哪些,哪些工具可以使用python语言开发软件
  • 留言与评论(共有 条评论)
       
    验证码: