像大神一樣使用和操作Python迭代器

像大神一樣使用和操作Python迭代器

文章目录

  • 如何遍歷 Python 可迭代型別
  • 1. 在列表中迴圈
  • 2. 迭代元組
  • 3. 迴圈瀏覽集合
  • 4. 遍歷字串
  • 5. 遍歷字典
  • 用 Python 中的 enumerate() 進行高階迭代
  • 如何實現 Python 生成器
  • 如何構建自定義迭代器
  • 可迭代函式
  • 高階可迭代操作
  • 1. 列表綜合
  • 2. Zip
  • 3. Filter
  • 4. Map
  • 5. Sorted
  • 如何處理迭代表中的邊緣情況和錯誤
  • 1. 空迭代表
  • 2. 巢狀迭代
  • 3. 異常處理
  • 小結

像大神一樣使用和操作Python迭代器

在 Python 程式設計中,理解並有效使用迭代表是熟練編碼的基礎。迭代表是可以遍歷或迴圈的物件。它們支援對其中的元素進行順序遍歷,是訪問和操作物件或資料結構中元素的重要工具。

本文通過重點介紹 Python 語言的內建可遍歷資料型別:列表、元組、字典、字串和集合,探討了如何正確使用 Python 可遍歷物件。它還解釋瞭如何實現自定義可遍歷型別和執行高階操作。

如何遍歷 Python 可迭代型別

在 Python 中,您可以使用 for 迴圈遍歷各種可遍歷型別。這使您能夠瀏覽序列,並對列表、集合和字典中的單個項執行操作。

Python 中的 for 關鍵字與 Java 等其他面嚮物件語言中的 for 關鍵字不同。Python for 迴圈的工作方式更像是迭代器方法。下面的示例演示了迭代表中的迴圈:

1. 在列表中迴圈

列表是有序的專案集合,可以使用 for 迴圈輕鬆迭代。

fruits_list = ["Apple", "Mango", "Peach", "Orange", "Banana"]
for fruit in fruits_list:
print(fruit)

在上面的程式碼中, fruit 充當迭代器,迴圈使用它來遍歷每個列表元素,同時列印它們。迴圈在評估完列表中的最後一個元素後終止。上述程式碼的輸出結果如下

Apple
Mango
Peach
Orange
Banana

2. 迭代元組

元組與列表類似,但不可變。您可以像遍歷列表一樣遍歷元組。

fruits_tuple = ("Apple", "Mango", "Peach", "Orange", "Banana")
for fruit in fruits_tuple:
print(fruit)

在此示例中, for 迴圈遍歷元組,在每次遍歷中,變數 fruit 取元組中當前元素的值。程式碼輸出如下:

Apple
Mango
Peach
Orange
Banana

3. 迴圈瀏覽集合

集合是由唯一元素組成的無序集合。您可以使用 for 迴圈遍歷它們。

fruits_set = {"Apple", "Mango", "Peach", "Orange", "Banana"}
for fruit in fruits_set:
print(fruit)

在本例中, for 迴圈對集合進行迭代。但是,由於集合是無序的,迭代的順序可能與集合中定義元素的順序不同。在每次迭代中,變數 fruit 都會取集合中當前元素的值。程式碼的輸出結果應與下面類似(順序可能不同):

Mango
Banana
Peach
Apple
Orange

4. 遍歷字串

字串是字元序列,可以逐個字元迴圈。

string = "Kinsta"
for char in string:
print(char)

上面的程式碼遍歷字串 “Wbolt”,並將每個字元列印到新行上。在每次迭代中,變數 char 的值都是字串中當前字元的值。程式碼的輸出結果如下

W
b
o
l
t

5. 遍歷字典

對於列表、集合、元組和字串來說, for 迴圈的使用方法類似,但對於字典來說就不同了,因為字典使用鍵值對來儲存條目。字典是一個獨特的迴圈案例,因為你可以使用不同的方法遍歷字典。下面是您可以用來遍歷 Python 字典的不同方法:

按鍵迭代:

countries_capital = {
"USA": "Washington D.C.",
"Australia": "Canberra",
"France": "Paris",
"Egypt": "Cairo",
"Japan": "Tokyo"
}
for country in countries_capital.keys():
print(country)

上面的程式碼定義了一個名為 countries_capital 的字典,其中國家名稱是鍵,它們各自的首都是值。for 迴圈使用 keys() 方法遍歷 countries_capital 字典中的鍵。該方法會返回一個檢視物件,顯示字典中的鍵值列表,這樣就可以方便地迴圈檢視所有鍵值。在每次迭代中,變數 country 都取當前鍵的值。這段程式碼的輸出結果如下:

USA
Australia
France
Egypt
Japan

迭代數值:

countries_capital = {
"USA": "Washington D.C.",
"Australia": "Canberra",
"France": "Paris",
"Egypt": "Cairo",
"Japan": "Tokyo"
}
for capital in countries_capital.values():
print(capital)

在上面的程式碼中, for 使用 values() 方法遍歷 countries_capital 字典中的值。該方法返回一個檢視物件,顯示字典中的值的列表,便於迴圈檢視所有值。在每次迭代中,變數 capital 都會取列表中當前值的值。這段程式碼的輸出結果如下

Washington D.C.
Canberra
Paris
Cairo
Tokyo

遍歷鍵值對:

countries_capital = {
"USA": "Washington D.C.",
"Australia": "Canberra",
"France": "Paris",
"Egypt": "Cairo",
"Japan": "Tokyo"
}
for country, capital in countries_capital.items():
print(country, ":", capital)

上面的程式碼演示瞭如何使用 items() 方法遍歷 countries_capital 字典的鍵和值。 items()  方法返回一個檢視物件,顯示字典中鍵值元組的列表。在 for 迴圈中,每次迭代都會從列表中的當前元素解包一個鍵值對。變數 countrycapital 分別被賦予相應的鍵和值。這段程式碼的輸出結果如下:

USA : Washington D.C.
Australia : Canberra
France : Paris
Egypt : Cairo
Japan : Tokyo

用 Python 中的 enumerate() 進行高階迭代

在返回元素索引和相應值的同時遍歷 Python 可迭代表的另一種方法是使用 enumerate() 函式。請看這個示例:

fruits_list = ["Apple", "Mango", "Peach", "Orange", "Banana"]
for index, fruit in enumerate(fruits_list):
print(fruit, index)

 

輸出結果如下:

Apple 0
Mango 1
Peach 2
Orange 3
Banana 4

 

enumerate 函式還允許您指定迭代操作的起始索引( 0 除外)。您可以將上面的示例修改如下:

fruits_list = ["Apple", "Mango", "Peach", "Orange", "Banana"]
for index, fruit in enumerate(fruits_list, start = 2):
print(fruit, index)

 

輸出結果如下:

Apple 2
Mango 3
Peach 4
Orange 5
Banana 6

 

請注意,雖然本示例指定了列舉的起始索引,但 enumerate 並不像本地列表那樣對可迭代元素應用基於零的索引。它只是將起始值附加到列表中的第一個元素,直到最後一個元素。

如何實現 Python 生成器

生成器是一種特殊的 Python 可迭代物件,它允許您構建生成器物件,而無需顯式地建立內建型別,如列表、集合或字典。您可以使用生成器來根據生成邏輯生成值。

生成器使用 yield 語句一次返回一個生成值。下面是一個生成器迭代的示例:

def even_generator(n):
counter = 0
while counter <= n:
if counter % 2 == 0:
yield counter
counter += 1
for num in even_generator(20):
print(num)

提供的程式碼定義了一個 even_generator 函式,該函式使用 yield 語句生成從 0 到指定 n 的偶數序列。它利用迴圈生成這些值,並使用 num 迭代器遍歷結果,確保對給定範圍內的所有值進行評估。如下所示,這段程式碼將輸出一個從 020 的偶數列表:

0
2
4
6
8
10
12
14
16
18
20

在使用生成器表示式時,您可以獲得更簡潔的效果。例如,您可以設計一個同時包含迴圈邏輯的生成器函式:

cube = (num ** 3 for num in range(1, 6))
for c in cube:
print(c)

在這裡,你將變數 cube 賦值給一個函式的結果,該函式計算 1 到 6 範圍內數值的立方。然後在指定範圍內迴圈取值,一個接一個地輸出計算結果。輸出結果如下:

1
8
27
64
125

如何構建自定義迭代器

Python 允許您使用迭代器進一步自定義可迭代操作。迭代器物件實現了迭代器協議,幷包含 2 個方法: __iter__()__next__()__iter__() 方法返回一個迭代器物件,而 __next__() 方法返回迭代器容器中的下一個值。下面是 Python 中的一個迭代器示例:

even_list = [2, 4, 6, 8, 10]
my_iterator = iter(even_list)
print(next(my_iterator)) # Prints 2
print(next(my_iterator)) # Prints 4
print(next(my_iterator)) # Prints 6

在這個示例中,你使用 iter() 方法從列表中建立了一個迭代器物件( my_iterator )。要訪問列表中的每個元素,需要用 next() 方法封裝迭代器物件。由於列表是有序集合,因此迭代器會按順序返回元素。

自定義迭代器非常適合涉及無法同時載入到記憶體中的大型資料集的操作。由於記憶體昂貴且容易受到空間限制,因此可以使用迭代器單獨處理資料元素,而無需將整個資料集載入到記憶體中。

可迭代函式

Python 使用函式來移動、操作和檢查列表元素。一些常用的 list 函式包括:

  • sum — 返回給定可迭代元素的總和,前提是集合為數值型別(整數、浮點數和複數)
  • any — 如果可迭代元素中有任何元素為真,則返回 true。否則返回 false 值。
  • all — 如果所有可迭代元素都為真,則返回 true。否則,返回 false
  • max — 返回給定可迭代集合的最大值
  • min — 返回給定可迭代集合的最小值
  • len — 返回給定可迭代集合的長度
  • append — 將一個值新增到可迭代列表的末尾

下面的示例用一個列表演示了這些函式:

even_list = [2, 4, 6, 8, 10]
print(sum(even_list))
print(any(even_list))
print(max(even_list))
print(min(even_list))
even_list.append(14) # Add 14 to the end of the list
print(even_list)
even_list.insert(0, 0) # Insert 0 and specified index [0]
print(even_list)
print(all(even_list)) # Return true only if ALL elements in the list are true
print(len(even_list)) # Print the size of the list

輸出結果如下:

30
True
10
2
[2, 4, 6, 8, 10, 14]
[0, 2, 4, 6, 8, 10, 14]
False
7

在上面的示例中, append 函式在列表末尾新增了一個引數( 14 )。 insert 函式允許指定插入索引。因此, even_list.insert(0, 0) 在索引 [0] 處插入了 0 。語句 print(all(even_list)) 返回 false,因為列表中有一個 0 值,解釋為 false。最後, print(len(even_list)) 輸出可迭代表的長度。

高階可迭代操作

Python 提供了一些高階特性,以提高可迭代操作的簡潔性。下面列出了其中一些。

1. 列表綜合

列表理解讓您可以通過對現有列表中的每個元素應用一個函式來建立新列表。下面是一個例子:

my_numbers = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
even_number_list = [num for num in my_numbers if num%2 == 0]
print(even_number_list)

在此程式碼片段中,建立了一個名為 my_numbers 的列表,其中包含從 1120 的整數。目的是生成一個新的 list,即 even_number_list ,其中只包含偶數整數。要實現這一目標,需要應用列表理解,只有當 my_numbers 中的整數為偶數時,才返回該整數。 if 語句包含返回偶數的邏輯。

下面是輸出結果:

[12, 14, 16, 18, 20]

2. Zip

Python 的 zip() 函式將多個迭代變數合併為元組。元組在一個變數中儲存多個值,並且不可變。下面介紹如何使用 zip() 合併迭代表:

fruits = ["apple", "orange", "banana"]
rating = [1, 2, 3]
fruits_rating = zip(rating, fruits)
print(list(fruits_rating))

在本例中, fruits_rating 將每個評級與一種水果配對,建立了一個迭代。輸出結果如下

[(1, 'apple'), (2, 'orange'), (3, 'banana')]

該程式碼是不同水果的評級系統,第一張列表(fruits)代表水果,第二張列表代表 1 到 3 級的評級。

3. Filter

另一個高階函式 filter 需要 2 個引數–一個函式和一個可迭代元素。它將函式應用於可迭代表中的每個元素,然後返回一個新的可迭代表,其中只包含函式返回 true 值的元素。下面的示例過濾了給定範圍內的整數值列表,只返回偶數值:

def is_even(n):
return n%2 == 0
nums_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_list = filter(is_even, nums_list)
print(list(even_list))

在上面的程式碼中,首先要定義一個函式 is_even ,用於計算傳遞給它的偶數。 然後,建立一個包含 1 到 10 之間整數值的列表 nums_list。最後,定義一個新的 list,即 even_list,使用 filter() 函式將使用者定義的方法應用於原始列表,並只返回偶數列表元素。結果如下:

[2, 4, 6, 8, 10]

4. Map

filter() 類似,Python 的 map() 函式也將一個可迭代元素和一個函式作為引數。但它不是返回初始可迭代的元素,而是返回一個新的可迭代,其中包含應用到第一個可迭代的每個元素的函式的結果。要對整數列表進行平方,請使用 map() 函式:

my_list = [2, 4, 6, 8, 10]
square_numbers = map(lambda x: x ** 2, my_list)
print(list(square_numbers))

在這段程式碼中, x 是遍歷列表並通過平方計算對其進行轉換的迭代器。 map() 函式將原始列表作為引數,與對映函式一起執行該操作。輸出結果如下

[4, 16, 36, 64, 100]

5. Sorted

sorted 函式按特定順序(升序或降序)對給定 iterable 中的元素進行排序,並以列表形式返回。該函式最多可接收 3 個引數: iterablereverse (可選)和 key (可選)。 key 是一個計算值的函式,用於確定 iterable 中元素的排序順序,預設值為 None。

下面的示例說明了如何在各種可迭代表中應用 sorted 函式:

# set
py_set = {'e', 'a', 'u', 'o', 'i'}
print(sorted(py_set, reverse=True))
# dictionary
py_dict = {'e': 1, 'a': 2, 'u': 3, 'o': 4, 'i': 5}
print(sorted(py_dict, reverse=True))
# frozen set
frozen_set = frozenset(('e', 'a', 'u', 'o', 'i'))
print(sorted(frozen_set, reverse=True))
# string
string = "kinsta"
print(sorted(string))
# list
py_list = ['a', 'e', 'i', 'o', 'u']
print(py_list)

輸出結果如下:

['u', 'o', 'i', 'e', 'a']
['u', 'o', 'i', 'e', 'a']
['u', 'o', 'i', 'e', 'a']
['a', 'i', 'k', 'n', 's', 't']
['a', 'e', 'i', 'o', 'u']

如何處理迭代表中的邊緣情況和錯誤

邊緣情況在許多程式設計場景中都很常見,你應該在迭代表中預見到它們。讓我們來探討一下可能遇到的幾種情況。

1. 空迭代表

當可迭代表為空,但某些程式設計邏輯試圖遍歷它時,您可能會遇到問題。你可以通過程式設計來解決這個問題,以避免效率低下。下面是一個使用 if not 語句檢查列表是否為空的示例:

fruits_list=[]
if not fruits_list:
print("The list is empty")

結果就是如此:

The list is empty

2. 巢狀迭代

Python 還支援巢狀迭代,即迭代物件中包含其他迭代物件。例如,您可以有一個食物列表,其中包含巢狀的食物類別列表,如肉類、蔬菜和穀物。下面介紹如何使用巢狀可迭代物件對這種情況進行建模:

food_list = [["kale", "broccoli", "ginger"], ["beef", "chicken", "tuna"], ["barley", "oats", "corn"]]
for inner_list in food_list:
for food in inner_list:
print(food)

在上面的程式碼中, food_list 變數包含三個巢狀列表,分別代表不同的食物類別。外迴圈( for inner_list in food_list: )遍歷主列表,內迴圈( for food in inner_list: )遍歷每個巢狀列表,列印每個食品專案。輸出結果如下

kale
broccoli
ginger
beef
chicken
tuna
barley
oats
corn

3. 異常處理

在 Python 中,迭代表還支援異常處理操作。例如,您可能在遍歷一個 list 時遇到 IndexError。這個錯誤意味著您試圖引用的元素超出了可迭代表的邊界。下面介紹如何使用 try-except 塊來處理這種異常:

fruits_list = ["apple", "mango", "orange", "pear"]
try:
print(fruits_list[5])
except IndexError:
print("The index specified is out of range.")

在上面的程式碼中, fruits_list 可迭代程式包含五個元素,分別由 list 集合中的索引 05 對映。 try 子句包含一個 print 函式,該函式試圖顯示迭代器索引 5 處的值,但該值並不存在。這將執行 except 子句,並返回相關的錯誤資訊。控制檯返回錯誤資訊:

The index specified is out of range.

小結

掌握 Python 中的迭代對於高效和可讀程式碼至關重要。瞭解對不同資料結構進行迭代的各種方法、使用理解、生成器以及利用內建函式,能讓你成為一名精通 Python 的程式設計師。

無論是處理列表、字典、字串還是自定義物件,瞭解如何使用和操作迭代都是 Python 程式設計中不可或缺的技能。

評論留言