今天小編給大家分享一下Python循環(huán)和迭代器怎么使用的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。
創(chuàng)新互聯(lián)自2013年創(chuàng)立以來(lái),先為大連等服務(wù)建站,大連等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢(xún)服務(wù)。為大連企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。
在 Python 中,與大多數(shù)語(yǔ)言一樣,有兩個(gè)基本的循環(huán):while
和for
。
while
循環(huán)是非常基本的。
clue = None while clue is None: clue = searchLocation()
clue is None
在這種情況下,只要循環(huán)條件的計(jì)算結(jié)果為True
,就會(huì)執(zhí)行循環(huán)的代碼。
在 Python 中,我們還有幾個(gè)有用的關(guān)鍵字:break
立即停止循環(huán),同時(shí)continue
跳到循環(huán)的下一次迭代。
break
最有用的方面之一是如果我們想要運(yùn)行相同的代碼,直到用戶(hù)提供有效的輸入。
while True: try: age = int(input("Enter your age: ")) except ValueError: print(f"Please enter a valid integer!") else: if age > 0: break
一旦我們遇到該break
語(yǔ)句,我們就退出循環(huán)。當(dāng)然,上面是一個(gè)較復(fù)雜的例子,但它證明了這一點(diǎn)。你還經(jīng)常看到while True:
在游戲循環(huán)中使用。
注意:如果你曾經(jīng)使用過(guò)任何語(yǔ)言的循環(huán),那么你已經(jīng)熟悉了無(wú)限循環(huán)(死循環(huán))。這通常是由while
條件計(jì)算結(jié)果為True
并且循環(huán)中沒(méi)有break
語(yǔ)句引起的。
來(lái)自 Java、C++ 或許多類(lèi)似的 ALGOL 風(fēng)格的語(yǔ)言,你可能熟悉三方for
循環(huán):for i := 1; i < 100; i := i + 1
。 我不了解你,但當(dāng)我第一次遇到這種情況時(shí),它嚇壞了我。我現(xiàn)在對(duì)它很滿意,但它不具備 Python 的優(yōu)雅簡(jiǎn)潔。
Python 的for
循環(huán)看起來(lái)大不相同。與上述偽代碼等效的 Python 代碼是...
for i in range(1,100): print(i)
range()是 Python 中一個(gè)特殊的“函數(shù)”,它返回一個(gè)序列。(從技術(shù)上講,它根本不是一個(gè)函數(shù)。)
這是 Python 令人印象深刻的地方——它迭代了一種特殊類(lèi)型的序列,稱(chēng)為iterable,我們稍后會(huì)談到。
目前,最容易理解的是我們可以迭代一個(gè)順序數(shù)據(jù)結(jié)構(gòu),比如一個(gè)數(shù)組(在 Python 中稱(chēng)為“列表”)。
因此,我們可以這樣做...
places = ['Nashville', 'Norway', 'Bonaire', 'Zimbabwe', 'Chicago', 'Czechoslovakia'] for place in places: print(place) print("...and back!")
我們得到這個(gè)...
Nashville Norway Bonaire Zimbabwe Chicago Czechoslovakia ...and back!
Python 在其循環(huán)中還有另一個(gè)獨(dú)特的小技巧:else
子句!循環(huán)完成后,沒(méi)有遇到break
語(yǔ)句,就會(huì)運(yùn)行else
。但是,如果手動(dòng)中斷循環(huán),它將else
完全跳過(guò)。
places = ['Nashville', 'Norway', 'Bonaire', 'Zimbabwe', 'Chicago', 'Czechoslovakia'] villain_at = 'Mali' for place in places: if place == villain_at: print("Villain captured!") break else: print("The villain got away again.")
由于“Mali”不在列表中,因此我們看到了“The villain got away again.”的消息。但是,如果我們將值更改villain_at
為Norway
,我們將看到“Villain captured!” ,而看不到了“The villain got away again.”。
Python 沒(méi)有do...while
循環(huán)。如果你正在尋找這樣的循環(huán)方式,典型的 Python 是使用while True:
帶內(nèi)部break
條件的 ,就像我們之前演示的那樣。
Python 有許多保存數(shù)據(jù)的容器或數(shù)據(jù)結(jié)構(gòu)。我們不會(huì)深入討論其中的任何一個(gè),但我想快速瀏覽一下最重要的部分:
list是一個(gè)可變序列(其實(shí)就是一個(gè)數(shù)組)。
它是用方括號(hào)定義的[ ]
,你可以通過(guò)索引訪問(wèn)它的元素。
foo = [2, 4, 2, 3] print(foo[1]) >>> 4 foo[1] = 42 print(foo) >>> [2, 42, 2, 3]
盡管對(duì)它沒(méi)有嚴(yán)格的技術(shù)要求,但典型的約定是列表只包含相同類(lèi)型的元素(“同質(zhì)”)。
tuple是一個(gè)不可變的序列。一旦你定義了它,你在技術(shù)上就不能改變它(回想一下之前不變性的含義)。這意味著在定義tuple后,你不能在tuple中添加或刪除元素。
一個(gè)tuple是在括號(hào)中定義的( )
,你可以通過(guò)索引訪問(wèn)它的元素。
foo = (2, 4, 2, 3) print(foo[1]) >>> 4 foo[1] = 42 >>> TypeError: 'tuple' object does not support item assignment
與列表不同,標(biāo)準(zhǔn)約定允許tuple包含不同類(lèi)型的元素(“異構(gòu)”)。
set是一個(gè)無(wú)序的可變集合,保證沒(méi)有重復(fù)。記住“無(wú)序”很重要:不能保證單個(gè)元素的順序!
一個(gè)集合在花括號(hào)中定義{ }
,但如果你想要一個(gè)空集合,你可以使用foo = set()
, 或者foo = {}
創(chuàng)建一個(gè)空的dict
. 你不能通過(guò)索引訪問(wèn)它的元素,因?yàn)樗菬o(wú)序的。
foo = {2, 4, 2, 3} print(foo) >>> {2, 3, 4} print(foo[1]) >>> TypeError: 'set' object does not support indexing
對(duì)于要添加到集合中的對(duì)象,它也必須是可散列的(hash)。一個(gè)對(duì)象是可散列的,如果:
它定義了方法__hash__(),該方法將哈希值(hash)作為整數(shù)返回。(見(jiàn)下文)
它定義了__eq__()比較兩個(gè)對(duì)象的方法。
對(duì)于同一個(gè)對(duì)象(值),一個(gè)有效的散列值(hash)應(yīng)該總是相同的,并且它應(yīng)該是合理的唯一的,因此另一個(gè)對(duì)象返回相同的散列是不常見(jiàn)的。(兩個(gè)或多個(gè)具有相同哈希值的對(duì)象稱(chēng)為哈希沖突,它們?nèi)匀粫?huì)發(fā)生。)
dict(字典)是鍵值數(shù)據(jù)結(jié)構(gòu)。
它在花括號(hào)中定義{ }
,:
用于分隔鍵和值。它是無(wú)序的,所以你不能通過(guò)索引訪問(wèn)它的元素;但是你可以通過(guò)[ ]
加鍵值訪問(wèn)元素。
foo = {'a' : 1, 'b' : 2, 'c' : 3, 'd' : 4} print(foo['b']) >>> 2 foo['b'] = 42 print(foo) >>> {'a': 1, 'b': 42, 'c': 3, 'd': 4}
只有可散列的對(duì)象可以用作字典鍵。(有關(guān)set
哈希性的更多信息,請(qǐng)參閱官網(wǎng)的部分。)
除了基礎(chǔ)之外,Python 還提供了額外的容器/數(shù)據(jù)結(jié)構(gòu)。可以在內(nèi)置模塊collections中找到它們。
有一個(gè)重要的 Python 語(yǔ)法我們還沒(méi)有討論過(guò),但很快就會(huì)派上用場(chǎng)。我們可以將容器中的每個(gè)元素分配給一個(gè)變量!這稱(chēng)為拆包。
當(dāng)然,我們需要確切地知道我們要拆包多少才能結(jié)束,否則我們會(huì)得到一個(gè)ValueError
的異常。
讓我們看一個(gè)使用tuple元組的基本示例。
fullname = ('Carmen', 'Sandiego') first, last = fullname print(first) >>> Carmen print(last) >>> Sandiego
看第二行代碼,我們可以列出多個(gè)要分配的變量,用逗號(hào)分隔。Python 將拆分等號(hào)右側(cè)的容器,將每個(gè)值按從左到右的順序分配給一個(gè)變量。
注意:記住,set
是無(wú)序的!雖然你可以在技術(shù)上使用集合來(lái)執(zhí)行此操作,但你無(wú)法確定將什么值分配給什么變量。不保證按順序進(jìn)行分配,集合的值的分配順序通常是偶然的!
Python 提供了一個(gè)關(guān)鍵字in
,用于檢查是否在容器中找到了特定元素。
places = ['Nashville', 'Norway', 'Bonaire', 'Zimbabwe', 'Chicago', 'Czechoslovakia'] if 'Nashville' in places: print("Music city!")
這適用于許多容器,包括列表、元組、集合,甚至是字典鍵(但不是字典值)。
如果你希望你的自定義類(lèi)之一支持in
運(yùn)算符,你只需要定義__contains__(self, item)
方法,它應(yīng)該返回True
or False
。
Python 的循環(huán)是配合我之前提到的迭代器一起使用。前面提到的數(shù)據(jù)結(jié)構(gòu)都是是可以使用迭代器迭代的對(duì)象。
好的,讓我們從頭開(kāi)始。Python 容器對(duì)象,例如 list
,也是一個(gè)可迭代對(duì)象,因?yàn)樗?code>__iter__()方法,返回一個(gè)迭代器對(duì)象。
方法__next__()
也是一個(gè)迭代器,在容器迭代器的情況下,返回下一項(xiàng)。即使是無(wú)序的容器,例如set()
,也可以使用迭代器進(jìn)行遍歷。
當(dāng)__next__()
不能返回任何其他內(nèi)容時(shí),它會(huì)拋出一個(gè)名為StopIteration的特殊異常。這可以使用try...except
捕獲異常。
讓我們?cè)倏匆幌?code>for遍歷 list
的循環(huán),例如...
dossiers = ['The Contessa', 'Double Trouble', 'Eartha Brute', 'Kneemoi', 'Patty Larceny', 'RoboCrook', 'Sarah Nade', 'Top Grunge', 'Vic the Slick', 'Wonder Rat'] for crook in dossiers: print(crook)
dossiers
是一個(gè)list
對(duì)象,它是一個(gè)可迭代的對(duì)象。當(dāng) Python 到達(dá)for
循環(huán)時(shí),它會(huì)做三件事:
調(diào)用iter(dossiers)
,依次執(zhí)行dossiers.__iter__()
。這將返回一個(gè)我們將調(diào)用的迭代器對(duì)象list_iter
。這個(gè)迭代器對(duì)象將被循環(huán)使用。
對(duì)于循環(huán)的每次迭代,它都會(huì)調(diào)用next(list_iter)
,執(zhí)行list_iter.__next__()
并將返回的值分配給crook
。
如果迭代器拋出了特殊異常StopIteration
,則循環(huán)結(jié)束,退出。
while True:
如果我在循環(huán)中重寫(xiě)該邏輯可能會(huì)更容易理解......
list_iter = iter(dossiers) while True: try: crook = next(list_iter) print(crook) except StopIteration: break
如果你嘗試這兩個(gè)循環(huán),你會(huì)發(fā)現(xiàn)它們做的事情完全相同!
了解__iter__()
,__next__()
和StopIteration
異常的工作原理后,你現(xiàn)在可以使自己的類(lèi)可迭代!
注意:雖然將迭代器類(lèi)與可迭代類(lèi)分開(kāi)定義都可以,但你不一定必須這樣做!只要這兩種方法都在你的類(lèi)中定義,并且__next__()
行為適當(dāng),你就可以定義__iter__()
為return self
.
值得注意的是迭代器本身是可迭代的:它們有一個(gè)__iter__()
方法返回self
。
假設(shè)我們有一本想要使用的字典......
locations = { 'Parade Ground': None, 'Ste.-Catherine Street': None, 'Pont Victoria': None, 'Underground City': None, 'Mont Royal Park': None, 'Fine Arts Museum': None, 'Humor Hall of Fame': 'The Warrant', 'Lachine Canal': 'The Loot', 'Montreal Jazz Festival': None, 'Olympic Stadium': None, 'St. Lawrence River': 'The Crook', 'Old Montréal': None, 'McGill University': None, 'Chalet Lookout': None, '?le Notre-Dame': None }
如果我們只想查看其中的每個(gè)項(xiàng)目,我們只需使用for
循環(huán)。所以,這應(yīng)該有效,對(duì)吧?
for location in locations: print(location)
哎呀!這只向我們展示了鍵,而不是值。這并不是我們想要的,不是嗎?
dict.__iter__()
返回一個(gè)dict_keyiterator
對(duì)象,該對(duì)象執(zhí)行其類(lèi)名的操作:它遍歷鍵,但不遍歷值。
要同時(shí)獲取鍵和值,我們需要調(diào)用locations.items()
返回dict_items
對(duì)象。dict_items.iter()
返回 dict_itemiterator
,它將字典中的每個(gè)鍵值對(duì)作為元組返回。
舊版說(shuō)明:如果你使用的是 Python 2,則應(yīng)改為調(diào)用locations.iteritems()
。
還記得剛才,當(dāng)我們談到拆包的時(shí)候嗎?我們將每一對(duì)鍵值作為一個(gè)元組并拆分成成兩個(gè)變量。
for key, value in locations.items(): print(f'{key} => {value}')
打印出以下內(nèi)容:
Parade Ground => None Ste.-Catherine Street => None Pont Victoria => None Underground City => None Mont Royal Park => None Fine Arts Museum => None Humor Hall of Fame => The Warrant Lachine Canal => The Loot Montreal Jazz Festival => None Olympic Stadium => None St. Lawrence River => The Crook Old Montréal => None McGill University => None Chalet Lookout => None ?le Notre-Dame => None
現(xiàn)在我們可以處理數(shù)據(jù)了。例如,我想在另一個(gè)字典中記錄重要信息。
information = {} for location, result in locations.items(): if result is not None: information[result] = location # Win the game! print(information['The Loot']) print(information['The Warrant']) print(information['The Crook']) print("Vic the Slick....in jaaaaaaaaail!")
這將找到 Loot、Warrant 和 Crook,并按正確順序列出它們:
Lachine Canal Humor Hall of Fame St. Lawrence River Vic the Slick....in jaaaaaaaaail!
我之前已經(jīng)提到你可以制作自己的迭代器和迭代器,但現(xiàn)在來(lái)實(shí)現(xiàn)它!
想象一下,我們想方便保留一個(gè)代理列表,以便我們始終可以通過(guò)代理編號(hào)來(lái)識(shí)別它們。但是,有些代理是我們不能談?wù)摰摹N覀兛梢酝ㄟ^(guò)將代理 ID 和名稱(chēng)存儲(chǔ)在字典中,然后維護(hù)分類(lèi)代理列表來(lái)輕松完成此操作。
注意:請(qǐng)記住,在我們對(duì)類(lèi)的討論中,Python 中實(shí)際上沒(méi)有私有變量這樣的東西。如果你真的打算保密,請(qǐng)使用行業(yè)標(biāo)準(zhǔn)的加密和安全實(shí)踐,或者至少不要將你的 API 暴露給任何 VILE 操作員。;)
對(duì)于初學(xué)者,這是該類(lèi)的基本結(jié)構(gòu):
class AgentRoster: def __init__(self): self._agents = {} self._classified = [] def add_agent(self, name, number, classified=False): self._agents[number] = name if classified: self._classified.append(name) def validate_number(self, number): try: name = self._agents[number] except KeyError: return False else: return True def lookup_agent(self, number): try: name = self._agents[number] except KeyError: name = "<NO KNOWN AGENT>" else: if name in self._classified: name = "<CLASSIFIED>" return name
我們可以繼續(xù)測(cè)試一下,只是為了后續(xù):
roster = AgentRoster() roster.add_agent("Ann Tickwitee", 2539634) roster.add_agent("Ivan Idea", 1324595) roster.add_agent("Rock Solid", 1385723) roster.add_agent("Chase Devineaux", 1495263, True) print(roster.validate_number(2539634)) >>> True print(roster.validate_number(9583253)) >>> False print(roster.lookup_agent(1324595)) >>> Ivan Idea print(roster.lookup_agent(9583253)) >>> <NO KNOWN AGENT> print(roster.lookup_agent(1495263)) >>> <CLASSIFIED>
太好了,這完全符合預(yù)期!現(xiàn)在,如果我們希望能夠遍歷整個(gè)字典怎么辦。
但是,我們不想直接訪問(wèn)roster._agents
字典,因?yàn)檫@將忽略這個(gè)類(lèi)的整個(gè)“分類(lèi)”方面。我們?nèi)绾翁幚恚?/p>
正如我之前提到的,我們可以讓這個(gè)類(lèi)也作為它自己的迭代器,這意味著它有一個(gè)__next__()
方法。在這種情況下,我們只會(huì) return self
。但是,這里是超簡(jiǎn)單Python教程,所以讓我們跳過(guò)煩人步驟,簡(jiǎn)化內(nèi)容,實(shí)際創(chuàng)建一個(gè)單獨(dú)的迭代器類(lèi)。
在這個(gè)例子中,我實(shí)際上將字典變成了一個(gè)元組列表,這將允許我使用索引。(請(qǐng)記住,字典是無(wú)序的。)我還將計(jì)算出有多少代理未分類(lèi)。當(dāng)然,所有這些邏輯都屬于該__init__()
方法:
class AgentRoster_Iterator: def __init__(self, container): self._roster = list(container._agents.items()) self._classified = container._classified self._max = len(self._roster) - len(self._classified) self._index = 0
要成為迭代器,類(lèi)必須有__next__()
方法;這是唯一的要求!請(qǐng)記住,一旦我們沒(méi)有更多數(shù)據(jù)要返回,該方法就需要拋出StopException
異常。
我將定義AgentRoster_Iterator
的__next__()
方法如下:
class AgentRoster_Iterator: # ...snip... def __next__(self): if self._index == self._max: raise StopIteration else: r = self._roster[self._index] self._index += 1 return r
現(xiàn)在我們返回到AgentRoster
類(lèi),我們需要在其中添加一個(gè)__iter__()
返回迭代器對(duì)象的方法。
class AgentRoster: # ...snip... def __iter__(self): return AgentRoster_Iterator(self)
只需要一點(diǎn)點(diǎn)操作,現(xiàn)在我們的AgentRoster
類(lèi)的行為與循環(huán)的預(yù)期完全一樣!這段代碼如下...
roster = AgentRoster() roster.add_agent("Ann Tickwitee", 2539634) roster.add_agent("Ivan Idea", 1324595) roster.add_agent("Rock Solid", 1385723) roster.add_agent("Chase Devineaux", 1495263, True) for number, name in roster: print(f'{name}, id #{number}')
產(chǎn)生的結(jié)果如下...
Ann Tickwitee, id #2539634 Ivan Idea, id #1324595 Rock Solid, id #1385723
以上就是“Python循環(huán)和迭代器怎么使用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
網(wǎng)站題目:Python循環(huán)和迭代器怎么使用
分享路徑:http://www.yijiale78.com/article8/piodip.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、網(wǎng)站導(dǎo)航、網(wǎng)站建設(shè)、品牌網(wǎng)站建設(shè)、全網(wǎng)營(yíng)銷(xiāo)推廣、域名注冊(cè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)