Python 中的 zip() 函式
在 Python 和所有程式語言中,我們可以使用 for
和 while
迴圈來迭代陣列。迭代單個陣列非常簡單。然而,當涉及到一起迭代多個陣列時,事情開始變得複雜。如果所有陣列的大小都相同,那麼這是一項簡單的工作。但是如果陣列大小不同,我們必須確保只考慮最小陣列的長度,以避免錯誤和異常。
Python 使這項任務變得容易得多。我們可以使用 Python 提供的內建實用程式,更準確地說是一個函式,而不是手動編寫用於迭代不同大小陣列的邏輯。這個函式是 zip()
函式。
本文將介紹 zip()
函式及其使用方法。
Python 中的 zip()
函式
zip()
函式接受可迭代物件(例如列表、字串和元組)作為引數並返回單個可迭代物件。
返回的可迭代物件具有最小可迭代物件的長度。例如,如果將兩個大小為 5
和 10
的列表提供給 zip()
函式,則返回的可迭代物件將具有 5
的長度。這意味著只有第二個列表的前 5
個元素將成為可迭代物件的一部分。如果給這個函式一個空的可迭代物件或沒有可迭代物件,它也返回一個空的可迭代物件。
現在我們已經完成了理論,讓我們看看如何使用這個功能。請參閱以下示例以瞭解其用法。
沒有可迭代物件
在以下 Python 程式碼中,不會將任何可迭代物件傳遞給 zip()
函式。
result = zip()
for x in result:
print(x)
當我們執行上述程式碼時,控制檯上不會列印任何內容。背後的原因很簡單;如果沒有提供可迭代物件,我們將沒有可迭代的內容。因此,返回一個空的可迭代物件。
相同長度的可迭代物件
在下面的 Python 程式碼中,一個整數元組、一個浮點值列表、一個類物件列表和一個相等長度的字串將被傳遞給 zip()
函式。
class Number:
def __init__(self, number):
self.number = number
def square(self):
return number ** 2
def __repr__(self):
return f"Number({self.number})"
a = (11, 22, 33, 44, 55)
b = [1.1, 2.2, 3.3, 4.4, 5.5]
c = [Number(1), Number(23), Number(44.44), Number(0), Number(-9)]
d = "Hello"
result = zip(a, b, c, d)
for x in result:
print(x)
輸出:
(11, 1.1, Number(1), 'H')
(22, 2.2, Number(23), 'e')
(33, 3.3, Number(44.44), 'l')
(44, 4.4, Number(0), 'l')
(55, 5.5, Number(-9), 'o')
正如我們所見,zip()
函式將所有可迭代物件的值一起儲存在元組中。元組中值的順序與將它們的可迭代物件提供給 zip()
函式的順序相同。
我們可以在 for
迴圈中解構或解壓縮這些值以便於訪問。請參閱以下程式碼。
class Number:
def __init__(self, number):
self.number = number
def square(self):
return number ** 2
def __repr__(self):
return f"Number({self.number})"
a = (11, 22, 33, 44, 55)
b = [1.1, 2.2, 3.3, 4.4, 5.5]
c = [Number(1), Number(23), Number(44.44), Number(0), Number(-9)]
d = "Hello"
result = zip(a, b, c, d)
for p, q, r, s in result:
print("A:", p)
print("B:", q)
print("C:", r)
print("D:", s)
輸出:
A: 11
B: 1.1
C: Number(1)
D: H
A: 22
B: 2.2
C: Number(23)
D: e
A: 33
B: 3.3
C: Number(44.44)
D: l
A: 44
B: 4.4
C: Number(0)
D: l
A: 55
B: 5.5
C: Number(-9)
D: o
除了使用 for
迴圈,我們還可以使用 while
迴圈對可迭代物件進行迭代。使用 while
迴圈,我們需要兩個額外的東西,next()
函式和 try-except
塊。next()
函式將用於從 zip()
函式返回的可迭代物件中獲取值,try...except
塊將用於停止迭代。請參閱以下 Python 程式碼。
class Number:
def __init__(self, number):
self.number = number
def square(self):
return number ** 2
def __repr__(self):
return f"Number({self.number})"
a = (11, 22, 33, 44, 55)
b = [1.1, 2.2, 3.3, 4.4, 5.5]
c = [Number(1), Number(23), Number(44.44), Number(0), Number(-9)]
d = "Hello"
result = zip(a, b, c, d)
while True:
try:
p, q, r, s = next(result)
print("A:", p)
print("B:", q)
print("C:", r)
print("D:", s)
except StopIteration:
break
輸出:
A: 11
B: 1.1
C: Number(1)
D: H
A: 22
B: 2.2
C: Number(23)
D: e
A: 33
B: 3.3
C: Number(44.44)
D: l
A: 44
B: 4.4
C: Number(0)
D: l
A: 55
B: 5.5
C: Number(-9)
D: o
當迭代器內沒有可用值時,它會引發 StopIteration
異常。使用 try-except
塊,我們捕獲此異常並退出無限 while
迴圈。
不同長度的可迭代物件
在下面的 Python 程式碼中,整數元組、浮點值列表、類物件列表和不同長度的字串將傳遞給 zip()
函式。
class Number:
def __init__(self, number):
self.number = number
def square(self):
return number ** 2
def __repr__(self):
return f"Number({self.number})"
a = (11, 22, 33)
b = [1.1, 2.2, 3.3, 4.4]
c = [Number(1), Number(23), Number(44.44), Number(0), Number(-9)]
d = "HelloWorld"
result = zip(a, b, c, d)
for p, q, r, s in result:
print("A:", p)
print("B:", q)
print("C:", r)
print("D:", s)
輸出:
A: 11
B: 1.1
C: Number(1)
D: H
A: 22
B: 2.2
C: Number(23)
D: e
A: 33
B: 3.3
C: Number(44.44)
D: l
所有可迭代物件都有不同的長度。第一個可迭代物件或整數元組的長度最小,3
。因此,輸出僅列印所有可迭代物件的前 3
個值。
建立字典
我們可以在 zip()
函式的幫助下建立一個鍵值對字典。這個想法是建立兩個長度相同的陣列的迭代器,包含鍵和它們各自的值,並在迭代返回的可迭代物件時將它們對映到字典中。請參閱以下程式碼。
import json
a = ["W", "O", "R", "L", "D"]
b = [1.1, True, "Hello", None, 5]
result = zip(a, b)
mapping = {x : y for x, y in result}
print(json.dumps(mapping, indent = 4))
輸出:
{
"W": 1.1,
"O": true,
"R": "Hello",
"L": null,
"D": 5
}
上面的程式碼只使用了 json
模組來美化字典的輸出。請注意,使用它是完全可選的。
將 zip()
函式與 enumerate()
函式一起使用
enumerate()
函式用於在迭代可迭代物件時同時獲取索引和值。由於 zip()
函式返回一個迭代器,我們可以將這兩個函式組合在一起並訪問索引和值。請參閱以下 Python 程式碼。
class Number:
def __init__(self, number):
self.number = number
def square(self):
return number ** 2
def __repr__(self):
return f"Number({self.number})"
a = (11, 22, 33)
b = [1.1, 2.2, 3.3, 4.4]
c = [Number(1), Number(23), Number(44.44), Number(0), Number(-9)]
d = "HelloWorld"
result = zip(a, b, c, d)
for i, (p, q, r, s) in enumerate(result):
print(f"A{i + 1}:", p)
print(f"B{i + 1}:", q)
print(f"C{i + 1}:", r)
print(f"D{i + 1}:", s)
輸出:
A1: 11
B1: 1.1
C1: Number(1)
D1: H
A2: 22
B2: 2.2
C2: Number(23)
D2: e
A3: 33
B3: 3.3
C3: Number(44.44)
D3: l
在上面的 Python 程式碼中,在 for
迴圈中,i, (p, q, r, s)
解包 enumerate()
函式返回的值,以及 (p, q, r, s)
解壓縮 zip()
函式返回的值。
enumerate()
函式返回的值採用以下格式。
(0, (11, 1.1, Number(1), 'H'))
(1, (22, 2.2, Number(23), 'e'))
(2, (33, 3.3, Number(44.44), 'l'))
它闡明瞭為什麼使用 i, (p, q, r, s)
來解包所有值。