pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

Python for 循環和迭代器行為

Python for loop and iterator behavior(Python for 循環和迭代器行為)
本文介紹了Python for 循環和迭代器行為的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我想進一步了解 iterators,所以如果我錯了,請糾正我.

I wanted to understand a bit more about iterators, so please correct me if I'm wrong.

迭代器是一個對象,它有一個指向下一個對象的指針,并被讀取為緩沖區或流(即鏈表).它們特別有效,因為它們所做的只是通過引用而不是使用索引來告訴您下一步是什么.

An iterator is an object which has a pointer to the next object and is read as a buffer or stream (i.e. a linked list). They're particularly efficient cause all they do is tell you what is next by references instead of using indexing.

但是我仍然不明白為什么會發生以下行為:

However I still don't understand why is the following behavior happening:

In [1]: iter = (i for i in range(5))

In [2]: for _ in iter:
   ....:     print _
   ....:     
0
1
2
3
4

In [3]: for _ in iter:
   ....:     print _
   ....:     

In [4]: 

在通過迭代器 (In [2]) 的第一個循環之后,就好像它被消耗并留空,所以第二個循環 (In [3])什么都不打印.

After a first loop through the iterator (In [2]) it's as if it was consumed and left empty, so the second loop (In [3]) prints nothing.

但是我從未為 iter 變量分配新值.

However I never assigned a new value to the iter variable.

for 循環的底層到底發生了什么?

What is really happening under the hood of the for loop?

推薦答案

你的懷疑是正確的:迭代器已經被消費了.

Your suspicion is correct: the iterator has been consumed.

實際上,您的迭代器是一個 generator,它是一個能夠只迭代一次.

In actuality, your iterator is a generator, which is an object which has the ability to be iterated through only once.

type((i for i in range(5))) # says it's type generator 

def another_generator():
    yield 1 # the yield expression makes it a generator, not a function

type(another_generator()) # also a generator

它們高效的原因與通過引用"告訴您下一步是什么無關.它們是高效的,因為它們只根據請求生成下一個項目;所有項目都不是一次生成的.事實上,你可以擁有一個無限的生成器:

The reason they are efficient has nothing to do with telling you what is next "by reference." They are efficient because they only generate the next item upon request; all of the items are not generated at once. In fact, you can have an infinite generator:

def my_gen():
    while True:
        yield 1 # again: yield means it is a generator, not a function

for _ in my_gen(): print(_) # hit ctl+c to stop this infinite loop!

其他一些有助于提高理解的更正:

Some other corrections to help improve your understanding:

  • 生成器不是指針,其行為方式與您在其他語言中可能熟悉的指針不同.
  • 與其他語言的區別之一:如上所述,生成器的每個結果都是動態生成的.在請求之前不會生成下一個結果.
  • 關鍵字組合 for in 接受一個可迭代對象作為其第二個參數.
  • 可迭代對象可以是生成器,如您的示例情況,但它也可以是任何其他可迭代對象,例如 listdict,或str 對象(字符串)或提供所需功能的用戶定義類型.
  • 應用了 iter 函數到對象以獲取迭代器(順便說一句:不要像您所做的那樣在 Python 中使用 iter 作為變量名 - 它是關鍵字之一).實際上,更準確地說,對象的 __iter__method 被調用(也就是說,在大多數情況下,所有 iter 函數無論如何都會執行;__iter__ 是 Python 所謂的魔術方法"之一).
  • 如果調用 __iter__ 成功,函數 next() 在循環中一遍又一遍地應用于可迭代對象,并將第一個變量提供給 for in 分配給 next() 函數的結果.(記住:可迭代對象可以是生成器,或者容器對象的迭代器,或者任何其他可迭代對象.)實際上,更準確地說:它調用迭代器對象的 __next__ 方法,這是另一種魔術方法".
  • for 循環在 next() 引發 StopIteration 異常(這通常發生在當調用 next() 時可迭代對象沒有要產生的另一個對象時).
  • The generator is not a pointer, and does not behave like a pointer as you might be familiar with in other languages.
  • One of the differences from other languages: as said above, each result of the generator is generated on the fly. The next result is not produced until it is requested.
  • The keyword combination for in accepts an iterable object as its second argument.
  • The iterable object can be a generator, as in your example case, but it can also be any other iterable object, such as a list, or dict, or a str object (string), or a user-defined type that provides the required functionality.
  • The iter function is applied to the object to get an iterator (by the way: don't use iter as a variable name in Python, as you have done - it is one of the keywords). Actually, to be more precise, the object's __iter__ method is called (which is, for the most part, all the iter function does anyway; __iter__ is one of Python's so-called "magic methods").
  • If the call to __iter__ is successful, the function next() is applied to the iterable object over and over again, in a loop, and the first variable supplied to for in is assigned to the result of the next() function. (Remember: the iterable object could be a generator, or a container object's iterator, or any other iterable object.) Actually, to be more precise: it calls the iterator object's __next__ method, which is another "magic method".
  • The for loop ends when next() raises the StopIteration exception (which usually happens when the iterable does not have another object to yield when next() is called).

您可以通過這種方式在 python 中手動"實現 for 循環(可能并不完美,但足夠接近):

You can "manually" implement a for loop in python this way (probably not perfect, but close enough):

try:
    temp = iterable.__iter__()
except AttributeError():
    raise TypeError("'{}' object is not iterable".format(type(iterable).__name__))
else:
    while True:
        try:
            _ = temp.__next__()
        except StopIteration:
            break
        except AttributeError:
            raise TypeError("iter() returned non-iterator of type '{}'".format(type(temp).__name__))
        # this is the "body" of the for loop
        continue

上面的代碼和你的示例代碼幾乎沒有區別.

There is pretty much no difference between the above and your example code.

實際上,for 循環中更有趣的部分不是for,而是in.單獨使用 in 會產生與 for in 不同的效果,但了解 in 的作用非常有用使用它的參數,因為 for in 實現了非常相似的行為.

Actually, the more interesting part of a for loop is not the for, but the in. Using in by itself produces a different effect than for in, but it is very useful to understand what in does with its arguments, since for in implements very similar behavior.

  • 單獨使用時,in 關鍵字首先調用對象的__contains__ 方法,又是一個神奇的方法"(注意使用for 時會跳過這一步在).在容器上單獨使用 in,您可以執行以下操作:

  • When used by itself, the in keyword first calls the object's __contains__ method, which is yet another "magic method" (note that this step is skipped when using for in). Using in by itself on a container, you can do things like this:

1 in [1, 2, 3] # True
'He' in 'Hello' # True
3 in range(10) # True
'eH' in 'Hello'[::-1] # True

  • 如果可迭代對象不是容器(即它沒有 __contains__ 方法),in 接下來會嘗試調用對象的 __iter__ 方法.如前所述:__iter__ 方法返回 Python 中已知的 迭代器.基本上,迭代器是一個對象,您可以使用內置的通用函數 next() on1.生成器只是迭代器的一種.

  • If the iterable object is NOT a container (i.e. it doesn't have a __contains__ method), in next tries to call the object's __iter__ method. As was said previously: the __iter__ method returns what is known in Python as an iterator. Basically, an iterator is an object that you can use the built-in generic function next() on1. A generator is just one type of iterator.

    如果您希望創建自己的對象類型以進行迭代(即,您可以使用 for in,或僅使用 in,on它),了解 yield 關鍵字很有用"noreferrer">生成器(如上所述).

    If you wish to create your own object type to iterate over (i.e, you can use for in, or just in, on it), it's useful to know about the yield keyword, which is used in generators (as mentioned above).

    class MyIterable():
        def __iter__(self):
            yield 1
    
    m = MyIterable()
    for _ in m: print(_) # 1
    1 in m # True    
    

    yield 的存在將函數或方法變成了生成器,而不是常規的函數/方法.如果您使用生成器,則不需要 __next__ 方法(它會自動帶來 __next__ ).

    The presence of yield turns a function or method into a generator instead of a regular function/method. You don't need the __next__ method if you use a generator (it brings __next__ along with it automatically).

    如果您希望創建自己的容器對象類型(即,您可以在其上單獨使用 in,但不能使用 for in),您只需要 __contains__ 方法.

    If you wish to create your own container object type (i.e, you can use in on it by itself, but NOT for in), you just need the __contains__ method.

    class MyUselessContainer():
        def __contains__(self, obj):
            return True
    
    m = MyUselessContainer()
    1 in m # True
    'Foo' in m # True
    TypeError in m # True
    None in m # True
    

    <小時>

    1 請注意,要成為迭代器,對象必須實現 迭代器協議.這僅意味著 __next____iter__ 方法都必須正確實現(生成器免費"提供此功能,所以你不要使用時無需擔心).還要注意 ___next__ 方法 實際上是 next(無下劃線)在 Python 2 中.


    1 Note that, to be an iterator, an object must implement the iterator protocol. This only means that both the __next__ and __iter__ methods must be correctly implemented (generators come with this functionality "for free", so you don't need to worry about it when using them). Also note that the ___next__ method is actually next (no underscores) in Python 2.

    2請參閱此答案了解創建可迭代類的不同方法.

    2 See this answer for the different ways to create iterable classes.

    這篇關于Python for 循環和迭代器行為的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

    【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!
  • 相關文檔推薦

    How to draw a rectangle around a region of interest in python(如何在python中的感興趣區域周圍繪制一個矩形)
    How can I detect and track people using OpenCV?(如何使用 OpenCV 檢測和跟蹤人員?)
    How to apply threshold within multiple rectangular bounding boxes in an image?(如何在圖像的多個矩形邊界框中應用閾值?)
    How can I download a specific part of Coco Dataset?(如何下載 Coco Dataset 的特定部分?)
    Detect image orientation angle based on text direction(根據文本方向檢測圖像方向角度)
    Detect centre and angle of rectangles in an image using Opencv(使用 Opencv 檢測圖像中矩形的中心和角度)
    主站蜘蛛池模板: 北京宣传片拍摄_产品宣传片拍摄_宣传片制作公司-现像传媒 | 米顿罗计量泵(科普)——韬铭机械 | 低噪声电流前置放大器-SR570电流前置放大器-深圳市嘉士达精密仪器有限公司 | 仓储笼_金属箱租赁_循环包装_铁网箱_蝴蝶笼租赁_酷龙仓储笼租赁 测试治具|过炉治具|过锡炉治具|工装夹具|测试夹具|允睿自动化设备 | 深圳装修_店面装修设计_餐厅设计_装修全包价格-尚泰装饰设计 | 低压载波电能表-单相导轨式电能表-华邦电力科技股份有限公司-智能物联网综合管理平台 | 焊锡丝|焊锡条|无铅锡条|无铅锡丝|无铅焊锡线|低温锡膏-深圳市川崎锡业科技有限公司 | 安徽免检低氮锅炉_合肥燃油锅炉_安徽蒸汽发生器_合肥燃气锅炉-合肥扬诺锅炉有限公司 | 隔离变压器-伺服变压器--输入输出电抗器-深圳市德而沃电气有限公司 | 3A别墅漆/3A环保漆_广东美涂士建材股份有限公司【官网】 | 华溶溶出仪-Memmert稳定箱-上海协烁仪器科技有限公司 | 【北京写字楼出租_写字楼租赁_办公室出租网/出售】-远行地产官网 | 断桥铝破碎机_发动机破碎机_杂铝破碎机厂家价格-皓星机械 | 智能终端_RTU_dcm_北斗星空自动化科技 | 昆明网络公司|云南网络公司|昆明网站建设公司|昆明网页设计|云南网站制作|新媒体运营公司|APP开发|小程序研发|尽在昆明奥远科技有限公司 | 无菌实验室规划装修设计-一体化实验室承包-北京洁净净化工程建设施工-北京航天科恩实验室装备工程技术有限公司 | 澳门精准正版免费大全,2025新澳门全年免费,新澳天天开奖免费资料大全最新,新澳2025今晚开奖资料,新澳马今天最快最新图库 | 美缝剂_美缝剂厂家_美缝剂加盟-地老板高端瓷砖美缝剂 | 蔡司三坐标-影像测量机-3D扫描仪-蔡司显微镜-扫描电镜-工业CT-ZEISS授权代理商三本工业测量 | 垃圾处理设备_餐厨垃圾处理设备_厨余垃圾处理设备_果蔬垃圾处理设备-深圳市三盛环保科技有限公司 | 掺铥光纤放大器-C/L波段光纤放大器-小信号光纤放大器-合肥脉锐光电技术有限公司 | 杭州中策电线|中策电缆|中策电线|杭州中策电缆|杭州中策电缆永通集团有限公司 | 步进_伺服_行星减速机,微型直流电机,大功率直流电机-淄博冠意传动机械 | 微型气象仪_气象传感器_防爆气象传感器-天合传感器大全 | 本安接线盒-本安电路用接线盒-本安分线盒-矿用电话接线盒-JHH生产厂家-宁波龙亿电子科技有限公司 | 立刷【微电签pos机】-嘉联支付立刷运营中心 | 拖鞋定制厂家-品牌拖鞋代加工厂-振扬实业中国高端拖鞋大型制造商 | 柔性测斜仪_滑动测斜仪-广州杰芯科技有限公司 | 工装定制/做厂家/公司_工装订做/制价格/费用-北京圣达信工装 | 送料机_高速冲床送料机_NC伺服滚轮送料机厂家-东莞市久谐自动化设备有限公司 | 塑胶跑道施工-硅pu篮球场施工-塑胶网球场建造-丙烯酸球场材料厂家-奥茵 | 二次元影像仪|二次元测量仪|拉力机|全自动影像测量仪厂家_苏州牧象仪器 | 拉卡拉POS机官网 - 官方直营POS机办理|在线免费领取 | 深圳天际源广告-形象堆头,企业文化墙,喷绘,门头招牌设计制作专家 | 菲希尔X射线测厚仪-菲希尔库伦法测厚仪-无锡骏展仪器有限责任公司 | 礼仪庆典公司,礼仪策划公司,庆典公司,演出公司,演艺公司,年会酒会,生日寿宴,动工仪式,开工仪式,奠基典礼,商务会议,竣工落成,乔迁揭牌,签约启动-东莞市开门红文化传媒有限公司 | 金刚网,金刚网窗纱,不锈钢网,金刚网厂家- 河北萨邦丝网制品有限公司 | 金刚网,金刚网窗纱,不锈钢网,金刚网厂家- 河北萨邦丝网制品有限公司 | 真空泵厂家_真空泵机组_水环泵_旋片泵_罗茨泵_耐腐蚀防爆_中德制泵 | 成都办公室装修-办公室设计-写字楼装修设计-厂房装修-四川和信建筑装饰工程有限公司 | 外观设计_设备外观设计_外观设计公司_产品外观设计_机械设备外观设计_东莞工业设计公司-意品深蓝 |