日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python 循环中的陷阱

發(fā)布時間:2025/3/20 python 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python 循环中的陷阱 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Python 中的 for 循環(huán)和其他語言中的 for 循環(huán)工作方式是不一樣的,今天就帶你深入了解 Python 的 for 循環(huán),看看它是如何工作的,以及它為什么按照這種方式工作。

循環(huán)中的陷阱

我們先來看一下 Python 循環(huán)中的「陷阱」,在我們了解了循環(huán)的工作方式后,再來看下這些陷阱到底是怎么出現(xiàn)的。

陷阱 1:循環(huán)兩次

現(xiàn)在我們先假設(shè)有一個數(shù)字組成的列表,和一個用于返回這些數(shù)字的平方的生成器:

>>> nums = [1, 2, 3, 4] >>> squares = (n**2 for n in nums)

我們可以將這個生成器對象傳遞給元組構(gòu)造器,從而可以得到一個元組:

>>> tuple(squares) (1, 4, 9, 16)

這個時候,如果我們再將這個構(gòu)造器對象傳遞給 sum 函數(shù),按理說應(yīng)該會返回這些數(shù)字的和吧:

>>> sum(squares) 0

返回的是個 0,先拖住下巴。

陷阱 2:檢查是否包含

我們還是使用上面的數(shù)字列表和生成器:

>>> nums = [1, 2, 3, 4] >>> squares = (n**2 for n in nums)

如果我 squares 生成器中是否包含 9,答案是肯定的,若果我再問一次呢?
你敢答應(yīng)嗎
你敢答應(yīng)嗎

''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:531509025 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' >>> 9 in squares True >>> 9 in squares False

發(fā)現(xiàn),第二次不靈了~

陷阱 3:拆包

現(xiàn)在假設(shè)有一個字典:

>>> counts = {1:'a', 2:'b'}

然后,我們用多個變量對字典進行拆包:

>>> x,y = counts

你覺得這時候,x 和 y 中會是什么?

>>> x 1 >>> y 2

我們只得到了鍵。

下面,我們先來了解下 Python 中的循環(huán)工作原理,然后再反過頭來看這些陷阱問題。

一些概念

首先,先了解一些基本概念:

可迭代和序列

可迭代就是指任意可以使用 for 循環(huán)遍歷的東西,可迭代意味著可以遍歷,任何可以遍歷的東西都是可迭代的。

for item in some_iterable:print(item)

序列是一種常見的可迭代類型,如列表、元組、字符串等。

序列是可迭代的,它有著一些特點,它們是從 0 開始索引,索引長度不超過序列的長度;它們有序列長度;并且它們可以被切分。

Python 中的大部分東西都是可以迭代的,但是可以迭代并不意味著它是序列。如集合、字典、文件和生成器都是可迭代的,但是它們都不是序列。

>>> my_set = {1, 2, 3} >>> my_dict = {'k1': 'v1', 'k2': 'v2'} >>> my_file = open('some_file.txt') >>> squares = (n**2 for n in my_set)

總結(jié)下來就是,任何可以用 for 循環(huán)遍歷的東西都是可迭代的,序列可迭代的類型中的一種,Python 還有著許多其他種類的可迭代類型。

迭代器

迭代器就是可以驅(qū)動可迭代對象的東西。你可以從任何可迭代對象中獲得迭代器,你也可以使用迭代器來手動對它的迭代進行遍歷。

下面有三個可迭代對象:一個集合、一個元祖和一個字符串:

>>> nums = {1,2,3,4} >>> coors = (4,5,6) >>> words = "hello hoxis"

我們可以使用 Python 的內(nèi)置函數(shù) iter ,從這些可迭代對象中獲取到迭代器:

>>> iter(nums) <setiterator object at 0x7fa8c194ad70> >>> iter(coors) <tupleiterator object at 0x7fa8c1959610> >>> iter(words) <iterator object at 0x7fa8c19595d0>

一旦我們有了迭代器,我們就可以使用其內(nèi)置函數(shù) next() 來獲取它的下一個值:

''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:531509025 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' >>> nums = {1,2,3,4} >>> num_iter = iter(nums) >>> next(num_iter) 1 >>> next(num_iter) 2 >>> next(num_iter) 3 >>> next(num_iter) 4 >>> next(num_iter) Traceback (most recent call last):File "<stdin>", line 1, in <module> StopIteration

若果迭代到頭了,也就是沒有下一個值了,就會拋出 StopIteration 異常。也就是說,它不會繼續(xù)循環(huán)取獲取第一個值。

是不是有點懵逼了?

  • 可迭代對象是可以迭代的東西
  • 迭代對象器實際上是遍歷可迭代對象的代理
  • 迭代器沒有長度,它們不能被索引。
  • 可以使用迭代器來做的唯一有用的事情是將其傳遞給內(nèi)置的 next 函數(shù),或者對其進行循環(huán)遍歷
  • 可以使用 list() 函數(shù)將迭代器轉(zhuǎn)換為列表
>>> nums = {1,2,3,4} >>> num_iter = iter(nums) >>> next(num_iter) 1 >>> list(num_iter) [2, 3, 4] >>> list(num_iter) []

若果想再次將其轉(zhuǎn)換為列表,明顯地,得到的是一個空列表。

其實這也是迭代器的一個重要特性:惰性,只能使用一次,只能循環(huán)遍歷一次。并且,在我們調(diào)用 next() 函數(shù)之前,它不會做任何事情。因此,我們可以創(chuàng)建無限長的迭代器,而創(chuàng)建無限長的列表則不行,那樣會耗盡你的內(nèi)存!

可迭代對象不一定是迭代器,但是迭代器一定是可迭代的:

對象可迭代?迭代器?
可迭代對象不一定
迭代器
生成器
列表×

其實,Python 中有許多迭代器,生成器是迭代器,Python 的許多內(nèi)置類型也是迭代器。例如,Python 的 enumerate 和 reversed 對象就是迭代器。zip, map 和 filter 也是迭代器;文件對象也是迭代器。

Python 中的 for 循環(huán)

其實,Python 并沒有傳統(tǒng)的 for 循環(huán),什么是傳統(tǒng)的 for 循環(huán)?

我們看下 Java 中的 for 循環(huán):

int[] integers = {1234}; for (int j = 0; j<integers.length; j++) {int i = integers[j];System.out.println(i); }

這是一種 C風格 的 for 循環(huán),JavaScript、C、C++、Java、PHP 和一大堆其他編程語言都有這種風格的 for 循環(huán),但是 Python 確實沒有。

Python 中的我們稱之為 for 循環(huán)的東西,確切的說應(yīng)該是 foreach 循環(huán):

numbers = [1, 2, 3, 5, 7] for n in numbers:print(n)

和 C風格 的 for 循環(huán)不同之處在于,Python 的 for 循環(huán)沒有索引變量,沒有索引變量的初始化,邊界檢查和索引變量的增長。

這就是 Python 的 for 循環(huán)的不同之處!

使用索引?

你可能會懷疑,Python 的 for 循環(huán)是否在底層使用了索引,下面我們手動的使用 while 循環(huán)和索引來遍歷:

''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:531509025 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' >>> nums = [1,2,3,4] >>> i = 0 >>> while i < len(nums): ... print(num[i]) ... i += 1 ... 0 1 2 3

對于列表,這樣遍歷是可以的,但不代表適用于所有可迭代對象,它只適用于序列。

比如,我們對一個 set 使用這種方法遍歷,會得到一個異常:

>>> set = {1,2,3} >>> i = 0 >>> while i < len(set): ... print(set[i]) ... i += 1 ... Traceback (most recent call last):File "<stdin>", line 2, in <module> TypeError: 'set' object does not support indexing

因為 set 不是序列,因此不支持索引遍歷。

我們不能使用索引手動對 Python 中的每一個迭代對象進行遍歷。對于那些不是序列的迭代器來說,更是行不通的。

實現(xiàn)沒有 for 的循環(huán)

從上文可以看出,Python 中的 for 循環(huán)不使用索引,它使用的是迭代器。讓我們來看下它是如何工作的。

通過上文,我們了解到了迭代器和 iter、next 函數(shù),現(xiàn)在我們可以嘗試不用 for 循環(huán)來遍歷一個可迭代對象。

下面是一個正常的 for 循環(huán):

def funky_for_loop(iterable, action_to_do):for item in iterable:action_to_do(item)

我們要嘗試用迭代器的方法和 while 實現(xiàn)上面 for 循環(huán)的邏輯,大致步驟如下:

  • 獲取給定可迭代對象的迭代器;
  • 調(diào)用迭代器的 next() 方法獲取下一項;
  • 對當前項數(shù)據(jù)進行處理;
  • 如果捕獲到 StopIteration ,那么就停止循環(huán)
def funky_for_loop(iterable, action_to_do):iterator = iter(iterable)while not done_looping:try:item = next(iterator)except StopIteration:breakelse:action_to_do(item)

Python 底層的循環(huán)工作方式基本上如上代碼,就是迭代器驅(qū)動的 for 循環(huán)。

再次回到循環(huán)陷阱

陷阱 1:耗盡的迭代器

陷阱 1 中,因為生成器是迭代器,迭代器是惰性的,也是一次性的,在已經(jīng)遍歷過一次的情況下,再對其求和,返回的就是一個 0。

陷阱 2:部分消耗迭代器

陷阱 2 中,我們兩次詢問 9 是否存在于同一個生成器中,得到了不同的答案。

這是因為,第一次詢問時,Python 已經(jīng)對這個生成器進行了遍歷,也就是調(diào)用 next() 函數(shù)查找 9,找到后就會返回 True,第二次再詢問 9 是否存在時,會從上次的位置繼續(xù) next() 查找。

''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:531509025 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' >>> nums = [1,2,3,4,5] >>> squares = (n**2 for n in nums) >>> 9 in squares True # 此時打印出來 >>> list(squares) [16, 25]

陷阱 3:拆包是迭代

當直接在字典上迭代時,得到的是鍵:

>>> counts = {1:'a',2:'b'} >>> for i in counts: ... print(i) ... 1 2

而對字典拆包時,和在字典上遍歷是一樣的,都是依賴于迭代器協(xié)議,因此得到的也是鍵。

總結(jié)

序列是迭代器,但是不是所有的迭代器都是序列。迭代器不可以被循環(huán)遍歷兩次、不能訪問其長度,也不能使用索引。

迭代器是 Python 中最基本的可迭代形式。如果你想在代碼中做一個惰性迭代,請考慮迭代器,并考慮使用生成器函數(shù)或生成器表達式。

最后,請記住,Python 中的每一種迭代都依賴于迭代器協(xié)議,因此理解迭代器協(xié)議是理解 Python 中的循環(huán)的關(guān)鍵。

總結(jié)

以上是生活随笔為你收集整理的Python 循环中的陷阱的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产成人精品一区二区 | 日本免费一区二区三区最新 | 国产亚洲小视频 | 冲田杏梨在线 | 中文在线一区 | 自拍偷拍麻豆 | 少妇一区二区三区 | 成人国产精品久久久 | 精品网站| 久久国产精品国语对白 | www.四虎在线 | 日韩a在线观看 | 亚洲欧美电影 | 毛片网在线观看 | 法国空姐在线观看视频 | 麻豆av一区二区三区 | 国产sss | 日韩av大全 | 亚洲天堂黄色 | 销魂奶水汁系列小说 | 男女插插视频 | 少妇太爽了太深了太硬了 | 精品www久久久久久奶水 | 老司机激情视频 | 爱如潮水3免费观看日本高清 | 密臀av在线播放 | 亚洲国产精品久久久久 | 日本免费看 | 国产精品久久久久一区二区三区 | 一区二区三区www污污污网站 | 劲爆欧美第一页 | 超碰c | 超污视频在线观看 | 成人18网站| 夜色伊人| 羞羞动态图 | 激情五月婷婷综合网 | 国产在线观看 | 天天干狠狠 | 阿的白色内裤hd中文 | 饥渴丰满的少妇喷潮 | 日韩性生交大片免费看 | av在线播放网 | 欧美有码在线 | 少妇高潮露脸国语对白 | 伊人福利 | 日韩在线一区视频 | 国产一区二区三区免费播放 | 香蕉视频亚洲 | 四虎一区二区三区 | 国产精品一区二三区 | 精品久久久久一区二区 | 久久三区| 日韩三级视频在线 | 久草视频福利在线 | 婷婷久久一区 | 美女扒开腿免费视频 | 天堂成人国产精品一区 | aaa欧美| www九九九| 美女视频黄a视频全免费观看 | 亚洲无av | 亚洲av永久无码国产精品久久 | 青青草综合视频 | 国产在线精品福利 | 日韩精品免费一区二区夜夜嗨 | melody在线高清免费观看 | 精品国产69 | 国产日韩大片 | 成人短视频在线播放 | 亚洲一区二区三区蜜桃 | 国产在线h | 李丽珍裸体午夜理伦片 | 亚洲gay视频 | av在线网站观看 | 孕妇一级片| 天天噜天天干 | 在线观看日韩国产 | 国产日韩一区二区在线观看 | 国产精品免费看片 | 国产免费黄色av | 内射合集对白在线 | av观看在线免费 | 不卡一二三 | 国产网站在线 | 免费黄色成人 | 五月视频 | 大战熟女丰满人妻av | 五月综合激情 | 国产成人在线免费视频 | xxxx国产精品 | 亚洲男女视频在线观看 | 黄色网址你懂得 | 欧美一级性视频 | 韩国精品在线观看 | 四虎影视在线播放 | www.色人阁| 热99这里只有精品 | 欧美激情第1页 |