溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Python迭代工具有哪些及怎么使用

發(fā)布時間:2022-10-10 17:52:52 來源:億速云 閱讀:123 作者:iii 欄目:web開發(fā)

今天小編給大家分享一下Python迭代工具有哪些及怎么使用的相關(guān)知識點,內(nèi)容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

range

它的功能比乍看起來要強大的多。

start和stop

使用range()的第一個要點是理解參數(shù):range(start, stop)start代表我們從start數(shù)字開始計數(shù),包含start這個數(shù)字;stop代表我們在到達stop數(shù)字后停止計數(shù),但不包括stop數(shù)字!

所以,如果我們有range(1, 10),就會得到[1, 2, 3, 4, 5, 6, 7, 8, 9]。開始于1,但不能到10。

如果我們想包含10在我們的序列中,我們需要range(1, 11)[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]。

順便說一句,如果我們只指定一個參數(shù),例如range(10),它將假定范圍的開始是0。在這種情況下,我們會得到[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]. 當(dāng)range()用于控制傳統(tǒng)的 for 循環(huán)時,你會經(jīng)??吹揭赃@種方式使用它。

step

我最喜歡range()的技巧是它的可選第三個參數(shù):當(dāng)你指定 range(start, stop, step)時,該step參數(shù)允許你每次增加大于1的值。

可以用在實現(xiàn)打印出 前100個7 的所有倍數(shù),從7自身到700,包括在內(nèi):range(7, 701, 7)會這樣做。(請注意,我最后指定了701,以確保包括700在內(nèi)。)

也可以用在打印所有小于 100的奇數(shù): range(1, 100, 2)。

return

如果你正在嘗試使用range,打印出7的所有倍數(shù),你可能會注意到結(jié)果并沒有達到你的預(yù)期:

sevens = range(7, 701, 7)
print(sevens)

print 命令打印文字短語range(7, 701, 7)。發(fā)現(xiàn)并不是我們想要的!

請記住,range()返回一個類似于迭代器的對象(python 2x返回的是列表)。要將其完全存儲為列表,我們需要通過將其包裝在函數(shù)list()中來將其轉(zhuǎn)換為列表:

sevens = list(range(7, 701, 7))
print(sevens)

現(xiàn)在輸出就是我們想要的——前100個 7 的倍數(shù)的列表!

分割

在我們進入所有這些新的迭代優(yōu)點之前,我想向你介紹擴展索引符號,它使我們能夠更強大地從有序容器中選擇元素,例如列表。

說到列表,來看看下面這個:

dossiers = ['Sir Vile', 'Dr. Belljar', 'Baron Grinnit', 'Medeva', 'General Mayhem', 'Buggs Zapper', 'Jacqueline Hyde', 'Jane Reaction', 'Dee Cryption']

不管你是否意識到,你已經(jīng)知道正常的索引符號。

print(dossiers[1])
>>> Dr. Belljar

這返回了容器的第二個元素(索引1) 。dossiers很簡單,對吧?幾乎所有語言都提供這種行為。

那么,如果我們想要第二個和第三個元素呢?

print(dossiers[1:3])
>>> ['Dr. Belljar', 'Baron Grinnit']

剛才發(fā)生了什么?在擴展索引表示法中,我們有三個參數(shù),用冒號分隔:start、stopstep。嘿,看起來很熟悉對吧?這些是range()使用的相同參數(shù)!它們的工作方式也完全相同。(當(dāng)然,我們在上面的示例中省略了第三個參數(shù) [ step]。)

請注意,該示例打印出Dr. Belljar(index 1) 和Baron Grinnit(index 2),但不是 Medeva,因為stop參數(shù)被迫停止了。

千萬要注意,start一定要小于 stop,你才能得到結(jié)果!不過有一個例外,我們稍后會談到。

現(xiàn)在,如果你想要從第二個開始的所有其他元素怎么辦?

print(dossiers[1::2])
>>> ['Dr. Belljar', 'Medeva', 'Buggs Zapper', 'Jane Reaction']

你會注意到我們沒有指定stop. 因為我們其實不需要!擴展索引符號允許你省略任何參數(shù),只要你有冒號來分隔開。由于省略了第二個參數(shù),我們只是將多余的:放在它本來應(yīng)該的位置之后。

反向分割

擴展索引符號使(start, stop, step)邏輯更進一步,允許你反向分割!一開始這有點繞腦筋,但是請堅持住……

print(dossiers[-1])

打印出列表中的最后一項。負數(shù)代表從列表末尾開始計數(shù)!這感覺有點奇怪,因為我們習(xí)慣于從0索引開始計數(shù),但負零并不是真正的有意義的數(shù),所以我們從-1開始。

鑒于此,我們?nèi)绾未蛴∽詈笕齻€項目?我們可能會這樣嘗試,但它實際上不起作用......

print(dossiers[-1:-4])
>>> []

這將返回一個空列表。為什么?請記住,start必須小于 stop,即使在使用負索引時也是如此。所以,我們必須把-4作為我們的start,因為-4 < -1。

print(dossiers[-4:-1])
>>> ['Buggs Zapper', 'Jacqueline Hyde', 'Jane Reaction']

這更接近了,但仍然存在問題。Dee Cryption是我們的最后一個元素,它在哪里呢?記住,stop是停止計數(shù)的數(shù)字,且不包含當(dāng)前數(shù)字。但我們不能只用dossiers[-4],因為那只會給我們Buggs Zapper。并且dossiers[-4:-0]是無效。

要解決這個問題的方法就是,告訴 Python 我們明確省略了第二個參數(shù):在我們的第一個參數(shù)后面加上一個冒號

print(dossiers[-4:])
>>> ['Buggs Zapper', 'Jacqueline Hyde', 'Jane Reaction', 'Dee Cryption']

現(xiàn)在我們得到了最后一個元素。如果我們想要最后三個,那就把-4改為-3......

print(dossiers[-3:])
>>> ['Jacqueline Hyde', 'Jane Reaction', 'Dee Cryption']

如果我們在第三個參數(shù)step中輸入一個負數(shù),你認為會發(fā)生什么?讓我們嘗試-1在它前面加上兩個冒號,表示我們想要整個列表。

print(dossiers[::-1])
>>> ['Dee Cryption', 'Jane Reaction', 'Jacqueline Hyde', 'Buggs Zapper', 'General Mayhem', 'Medeva', 'Baron Grinnit', 'Dr. Belljar', 'Sir Vile']

看起來這是將所有內(nèi)容都逆向打印除了!事實上,  step設(shè)置為-1顛倒了列表。

現(xiàn)在讓我們嘗試-2...

print(dossiers[::-2])
>>> ['Dee Cryption', 'Jacqueline Hyde', 'General Mayhem', 'Baron Grinnit', 'Sir Vile']

這不僅反轉(zhuǎn)了列表,而且跳過了所有部分元素。負數(shù)的step行為與正數(shù)完全相同step,只是它逆向工作!

那么,如果我們想把所有東西放在一起怎么辦?也許我們想以相反的順序列出第二個、第三個和第四個元素......

print(dossiers[2:5:-1])
>>> []

注意: startstop必須按順序遍歷。如果step為正,則start必須小于stop;但是,如果step為負數(shù),則start必須大于stop!

你可以把它想象成攝影之旅的步行路線。step告訴你走哪條路,你的步幅應(yīng)該有多大。一到就開始拍照start,一遇到問題就stop收起相機。

所以,要解決這個問題,我們需要交換我們的startand stop。

print(dossiers[5:2:-1])
>>> ['Buggs Zapper', 'General Mayhem', 'Medeva']

說明: Python 還提供了slice()anditertools.islice()函數(shù),它們的行為方式大致相同。但是,它們都比擴展索引符號更受限制,因此你最好使用擴展索引符號而不是函數(shù)。

操作迭代對象

我們將在本節(jié)中探索的其余函數(shù)都與迭代對象一起使用。雖然我將在大多數(shù)示例中使用列表,但請記住,你可以使用任何可迭代的對象,包括range()函數(shù)。

all和any

想象一下,你在一個可迭代的容器(例如列表)中獲得了一大堆數(shù)據(jù),例如包含數(shù)百個名稱的列表。在將該列表輸入到你的超級算法之前,你希望通過檢查每個元素中是否存在異常值來節(jié)省一些處理時間。

這就是all函數(shù)的用途。

dossiers = ['Sir Vile', 'Dr. Belljar', 'Baron Grinnit', 'Medeva', 'General Mayhem', 'Buggs Zapper', '', 'Jane Reaction', 'Dee Cryption']
print(all(dossiers))
>>> False

你可能還記得,空字符串 ( '')在 Python 中的計算結(jié)果為False。該all()函數(shù)評估每個元素,并確保它返回True。如果甚至一個計算結(jié)果為False,該all()函數(shù)也將返回 false。

any()以幾乎相同的方式工作,但是它只需要一個元素來評估True.

乍一看,這些似乎不是很有用,但是當(dāng)與其他一些工具結(jié)合使用時,甚至與列表解析(稍后部分)結(jié)合使用時,它們可以節(jié)省大量時間!

enumerate

在循環(huán)中,如果你需要訪問列表的及其索引,你可以使用該enumerate()函數(shù)來完成。

foo = ['A', 'B', 'C', 'D', 'E']

for index, value in enumerate(foo):
    print(f'Element {index} is has the value {value}.')

但是enumerate(),不僅限于列表。像所有這些其他函數(shù)一樣,它適用于任何可迭代的對象,需要返回編號(或枚舉)的每個值。例如,我們把它用在range()。讓我們用它來打印從 10 到 100 ( range(10,101,10)) 的每一個 10 的倍數(shù)。下面是舉例...

for index, value in enumerate(range(10,101,10)):
    print(f'Element {index} is has the value {value}.')

這給了我們...

Element 0 is has the value 10.
Element 1 is has the value 20.
Element 2 is has the value 30.
Element 3 is has the value 40.
Element 4 is has the value 50.
Element 5 is has the value 60.
Element 6 is has the value 70.
Element 7 is has the value 80.
Element 8 is has the value 90.
Element 9 is has the value 100

我們可以從中得出一個簡潔的模式,但我們必須從1而不是0開始枚舉。果然,我們可以通過傳遞起始計數(shù)數(shù)字作為第二個參數(shù)來實現(xiàn)。我們還將稍微調(diào)整我們輸出的信息,簡化一下輸出格式。

for index, value in enumerate(range(10,101,10), 1):
    print(f'{index} times 10 equals {value}')

當(dāng)我們運行它時,我們得到...

1 times 10 equals 10
2 times 10 equals 20
3 times 10 equals 30
4 times 10 equals 40
5 times 10 equals 50
6 times 10 equals 60
7 times 10 equals 70
8 times 10 equals 80
9 times 10 equals 90
10 times 10 equals 100

filter

假設(shè)我們正在跟蹤在一堆地點找到的線索數(shù)量,將它們存儲在字典中。對于這個例子,我將在最后一節(jié)中借用和調(diào)整字典......

locations = {
    'Parade Ground': 0,
    'Ste.-Catherine Street': 0,
    'Pont Victoria': 0,
    'Underground City': 3,
    'Mont Royal Park': 0,
    'Fine Arts Museum': 0,
    'Humor Hall of Fame': 2,
    'Lachine Canal': 4,
    'Montreal Jazz Festival': 1,
    'Olympic Stadium': 0,
    'St. Lawrence River': 2,
    'Old Montréal': 0,
    'McGill University': 0,
    'Chalet Lookout': 0,
    '?le Notre-Dame': 0
    }

也許我們需要找到所有有線索的地點,而忽略其余的。我們將首先編寫一個函數(shù)來測試特定的鍵值元組對。這似乎是一個荒謬的過度復(fù)雜化,但一會兒會有用:

def has_clues(pair):
    return bool(pair[1])

我們將字典中的每一對作為元組提交給函數(shù),pair[1]將會是值(例如('Underground City', 3))。如果線索數(shù)字是0,bool()函數(shù)將返回False,那其他所有為True的元素,就是我們想要的。

我們使用filter()對剛剛編寫的函數(shù)來縮小字典范圍。回想一下上一節(jié),我們需要使用locations.items()來獲取鍵和值作為一對。

for place, clues in filter(has_clues, locations.items()):
    print(place)

請注意,我們不包括has_clues 后面的括號。我們將實際函數(shù)作為對象傳遞!filter將進行實際調(diào)用。

果然,運行該代碼會打印出我們有線索的五個地點(值 > 0)......

Underground City
Humor Hall of Fame
Lachine Canal
Montreal Jazz Festival
St. Lawrence River

在本系列的后面部分,我們將學(xué)習(xí) lambdas匿名函數(shù),我們不用單獨定義函數(shù)。代碼如下......

for place, clues in filter(lambda x:bool(x[1]), locations.items()):
    print(place)

map

map()函數(shù)的方式與 類似filter(),只是它不是使用函數(shù)從可迭代對象中省略元素,而是用于更改它們。

假設(shè)我們有一個華氏溫度列表:

temps = [67.0, 72.5, 71.3, 78.4, 62.1, 80.6]

我們想將這些都轉(zhuǎn)換為攝氏度,所以我們?yōu)榇司帉懥艘粋€函數(shù)。

def f_to_c(temp):
    return round((temp - 32) / 1.8, 1)

我們可以使用該map()函數(shù)將其應(yīng)用于temps 中的每個值,從而生成可以在循環(huán)(或任何地方)中使用的迭代器。

for c in map(f_to_c, temps):
    print(f'{c}°C')

請記住,我們將函數(shù)對象 f_to_c作為map() 的第一個參數(shù)傳遞,所以我們?nèi)サ衾ㄌ枺?/p>

運行該循環(huán)輸出:

19.4°C
22.5°C
21.8°C
25.8°C
16.7°C
27.0°C

min和max

讓我們繼續(xù)使用剛剛的溫度列表例子。如果我們想在列表中找到最低最高,我們可以分別使用min()ormax()函數(shù)。這沒什么新奇的。

temps = [67.0, 72.5, 71.3, 78.4, 62.1, 80.6]
print(min(temps))
>>> 62.1
print(max(temps))
>>> 80.6

注意:與可迭代對象無關(guān),你還可以使用這些函數(shù)來查找你提供給它的參數(shù)列表中的最小或最大參數(shù),例如min(4, 5, 6, 7, 8),這將返回4。

sorted

通常,你需要對可迭代對象進行排序。Python 通過sorted()內(nèi)置函數(shù)非常有效地做到了這一點。

temps = [67.0, 72.5, 71.3, 78.4, 62.1, 80.6]
for t in sorted(temps):
    print(t)

輸出如下...

62.1
67.0
71.3
72.5
78.4
80.6

reversed

大多數(shù)時候,擴展索引符號[::-1]將允許你反轉(zhuǎn)列表或其他有序迭代。但如果這不是唯一辦法,你也可以使用reversed()函數(shù)來反轉(zhuǎn)。

例如,我用sorted()與剛才的函數(shù)結(jié)合起來......

temps = [67.0, 72.5, 71.3, 78.4, 62.1, 80.6]
for t in reversed(sorted(temps)):
    print(t)

程序輸出如下...

80.6
78.4
72.5
71.3
67.0
62.1

sum

另一個快速的內(nèi)置函數(shù)是sum(),它將迭代中的所有元素添加在一起。當(dāng)然,這只有在所有元素可以添加在一起時才有效。

這樣做的一種用途是更早地找到這些溫度的平均值。你可能還記得該len()函數(shù)告訴我們?nèi)萜髦杏卸嗌僭亍?/p>

temps = [67.0, 72.5, 71.3, 78.4, 62.1, 80.6]
average = sum(temps) / len(temps)
print(round(average, 2))
>>> 71.98

zip

還記得前面那個關(guān)于地點和線索的例子嗎?想象一下,我們得到的信息不是在字典中,而是在兩個列表中:

locations = ['Parade Ground', 'Ste.-Catherine Street', 'Pont Victoria', 'Underground City', 'Mont Royal Park', 'Fine Arts Museum', 'Humor Hall of Fame', 'Lachine Canal', 'Montreal Jazz Festival', 'Olympic Stadium', 'St. Lawrence River', 'Old Montréal', 'McGill University', 'Chalet Lookout', '?le Notre-Dame']
clues = [0, 0, 0, 3, 0, 0, 2, 4, 1, 0, 2, 0, 0, 0, 0]

那么剛剛的方法就不能實現(xiàn)查找了,但是在現(xiàn)實世界中確實存在我們會以這種方式獲取數(shù)據(jù)的場景。

值得慶幸的是,zip()函數(shù)可以幫助我們處理這些數(shù)據(jù),方法是使用迭代器將其聚合成元組,給我們(locations[0], clues[0]), (locations[1], clues[1]), (locations[2], clues[2])等等。

zip()函數(shù)甚至不限于兩個迭代;它可以盡可能多地壓縮在一起!如果迭代的長度不同,“額外”內(nèi)容會被放到最后。

當(dāng)然,在這種情況下,兩個列表的長度相同,所以結(jié)果是相當(dāng)明顯的。讓我們使用 zip 中的數(shù)據(jù)創(chuàng)建一個新列表,并將其打印出來。

data = list(zip(locations, clues))
print(data)

這給了我們一個與我們.items()之前從字典函數(shù)中得到的結(jié)構(gòu)不同的結(jié)構(gòu)!

[('Parade Ground', 0), ('Ste.-Catherine Street', 0), ('Pont Victoria', 0), ('Underground City', 3), ('Mont Royal Park', 0), ('Fine Arts Museum', 0), ('Humor Hall of Fame', 2), ('Lachine Canal', 4), ('Montreal Jazz Festival', 1), ('Olympic Stadium', 0), ('St. Lawrence River', 2), ('Old Montréal', 0), ('McGill University', 0), ('Chalet Lookout', 0), ('?le Notre-Dame', 0)]

事實上,如果我回憶起我filter()的 lambda 函數(shù),我可以將它調(diào)整為 use zip,讓我們完全從兩個列表中工作:

for place, clues in filter(lambda x:bool(x[1]), zip(locations, clues)):
    print(place)

和以前一樣,輸出...

Underground City
Humor Hall of Fame
Lachine Canal
Montreal Jazz Festival
St. Lawrence River

itertools

我已經(jīng)介紹了幾乎所有 Python 用于處理可迭代對象的內(nèi)置函數(shù),但itertools模塊中還有更多內(nèi)容。我強烈建議閱讀官方文檔以了解更多信息。

以上就是“Python迭代工具有哪些及怎么使用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI