Python zip() 函數詳解:新手指南

更新日期: 2024 年 10 月 3 日

在 Python 編程中,zip() 函數 是一個非常實用的內建函數,允許我們同時遍歷多個迭代器,並將它們的元素配對組合。

對於剛開始學習 Python 的新手來說,理解並掌握 zip() 函數的用法,將大大提升您的編程效率和代碼可讀性。

本文將詳細介紹 Python 中的 zip() 函數,包括其基本概念、語法、使用方法、實際應用和注意事項,幫助您在實際開發中靈活運用。


什麼是 zip() 函數?

zip() 函數是一個內建函數,用於將多個 迭代器(iterable)(如串列、元組、字串等)中的元素打包成一個個元組,然後返回這些元組組成的迭代器。

簡單來說zip() 函數可以同時遍歷多個迭代器,並在遍歷的過程中將對應位置的元素組合在一起。

zip() 函數的基本語法

zip(*iterables)
  • *iterables:任意數量的可迭代物件。
  • 返回值:一個 zip 物件,該物件是一個迭代器,產生由各個迭代器對應元素組成的元組。

示例:

numbers = [1, 2, 3]
letters = ['a', 'b', 'c']

zipped = zip(numbers, letters)
print(list(zipped))

輸出:

[(1, 'a'), (2, 'b'), (3, 'c')]

將串列進行配對

示例:

names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]

paired = zip(names, ages)
print(list(paired))

輸出:

[('Alice', 25), ('Bob', 30), ('Charlie', 35)]

解釋:

  • zip(names, ages) 生成一個迭代器,每次迭代返回一個元組,包含 namesages 中對應位置的元素。

與不同類型的迭代器一起使用

zip() 函數不僅可以處理串列,還可以處理元組、字串和其他可迭代物件。

示例:

numbers = (1, 2, 3)
letters = 'abc'
floats = [1.0, 2.0, 3.0]

zipped = zip(numbers, letters, floats)
print(list(zipped))

輸出:

[(1, 'a', 1.0), (2, 'b', 2.0), (3, 'c', 3.0)]

解釋:

  • numbers 是元組,letters 是字串,floats 是串列。
  • zip() 可以同時處理這些不同類型的迭代器。

遍歷 zip() 物件

zip() 返回一個迭代器,可以使用 for 迴圈直接遍歷。

示例:

names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]

for name, age in zip(names, ages):
    print(f"{name} is {age} years old.")

輸出:

Alice is 25 years old.
Bob is 30 years old.
Charlie is 35 years old.

解釋:

  • for 迴圈中,nameage 對應每個元組中的元素。

zip() 結果轉換為其他結構

轉換為串列

numbers = [1, 2, 3]
letters = ['a', 'b', 'c']

zipped_list = list(zip(numbers, letters))
print(zipped_list)

輸出:

[(1, 'a'), (2, 'b'), (3, 'c')]

轉換為字典

keys = ['name', 'age', 'city']
values = ['Alice', 25, 'Taipei']

result_dict = dict(zip(keys, values))
print(result_dict)

輸出:

{'name': 'Alice', 'age': 25, 'city': 'Taipei'}

解釋:

  • 使用 dict() 函數將 zip() 的結果轉換為字典,鍵和值來自兩個串列。

解壓縮已壓縮的迭代器

使用 * 運算子,可以將已經壓縮的迭代器解壓縮回原來的形式。

示例:

zipped = [('Alice', 25), ('Bob', 30), ('Charlie', 35)]
names, ages = zip(*zipped)

print(names)  # 輸出:('Alice', 'Bob', 'Charlie')
print(ages)   # 輸出:(25, 30, 35)

解釋:

  • zip(*zipped) 反向操作,將元組串列解壓縮成單獨的元組。

處理不同長度的迭代器

當提供給 zip() 的迭代器長度不一致時,zip() 會以最短的迭代器為準,忽略多餘的元素。

示例:

numbers = [1, 2, 3, 4]
letters = ['a', 'b']

zipped = zip(numbers, letters)
print(list(zipped))

輸出:

[(1, 'a'), (2, 'b')]

解釋:

  • 只配對了前兩個元素,因為 letters 只有兩個元素。

使用 itertools.zip_longest()

如果需要在處理長度不一致的迭代器時保留所有元素,可以使用 itertools 模組的 zip_longest() 函數。

示例:

from itertools import zip_longest

numbers = [1, 2, 3, 4]
letters = ['a', 'b']

zipped = zip_longest(numbers, letters, fillvalue='N/A')
print(list(zipped))

輸出:

[(1, 'a'), (2, 'b'), (3, 'N/A'), (4, 'N/A')]

解釋:

  • zip_longest() 會繼續配對,使用 fillvalue 填充缺失的值。

實際應用示例

同時遍歷多個串列

questions = ['name', 'quest', 'favorite color']
answers = ['Lancelot', 'To seek the Holy Grail', 'Blue']

for question, answer in zip(questions, answers):
    print(f"What is your {question}?  It is {answer}.")

輸出:

What is your name?  It is Lancelot.
What is your quest?  It is To seek the Holy Grail.
What is your favorite color?  It is Blue.

創建字典

fields = ['name', 'age', 'gender']
values = ['Alice', 30, 'Female']

person = dict(zip(fields, values))
print(person)

輸出:

{'name': 'Alice', 'age': 30, 'gender': 'Female'}

轉置矩陣

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

transposed = list(zip(*matrix))
print(transposed)

輸出:

[(1, 4, 7), (2, 5, 8), (3, 6, 9)]

解釋:

  • *matrix:使用解包運算符,將矩陣中的每個子列表作為單獨的參數傳遞給 zip() 函數。
zip(matrix[0], matrix[1], matrix[2])
# 即
zip([1, 2, 3], [4, 5, 6], [7, 8, 9])
  • zip() 函數的作用:接受多個可迭代對象,將它們對應位置的元素打包成一個個元組,返回一個迭代器。
  • 應用在此處
  zip([1, 2, 3], [4, 5, 6], [7, 8, 9])
  • zip() 的結果
    • 將每個列表的 第一個元素 組成一個元組: (1, 4, 7)
    • 將每個列表的 第二個元素 組成一個元組: (2, 5, 8)
    • 將每個列表的 第三個元素 組成一個元組: (3, 6, 9)
  • 因此,zip(*matrix) 生成的迭代器包含以下元組
  (
    (1, 4, 7),
    (2, 5, 8),
    (3, 6, 9)
  )
  • list() 函數:將 zip() 返回的迭代器轉換為列表,方便查看和使用。
  [
    (1, 4, 7),
    (2, 5, 8),
    (3, 6, 9)
  ]

3. 打印轉置後的矩陣

print(transposed)

輸出結果:

[(1, 4, 7), (2, 5, 8), (3, 6, 9)]

解釋:

  • 原矩陣的行和列已經互換
  • 第一行(1, 4, 7),原矩陣的 第一列
  • 第二行(2, 5, 8),原矩陣的 第二列
  • 第三行(3, 6, 9),原矩陣的 第三列

注意事項

zip() 返回的是迭代器

  • 在 Python 3 中,zip() 返回一個迭代器,而不是串列。
  • 如果需要多次使用,應轉換為串列或其他可重複使用的結構。

迭代器耗盡

  • 一旦將 zip() 物件轉換為串列或遍歷過,迭代器就會耗盡,需要重新生成。 示例:
  zipped = zip([1, 2, 3], ['a', 'b', 'c'])
  print(list(zipped))  # 輸出:[(1, 'a'), (2, 'b'), (3, 'c')]
  print(list(zipped))  # 輸出:[]

處理不同長度的迭代器

  • 默認情況下,zip() 以最短的迭代器為準,忽略多餘元素。如需保留所有元素,請使用 itertools.zip_longest()

注意內存使用

  • 當處理大型數據集時,zip() 可以高效地處理,因為它返回的是迭代器,不會一次性將所有數據加載到內存中。

結論

  • zip() 函數 是 Python 中強大的工具,允許我們同時遍歷多個迭代器,並將對應位置的元素組合在一起。
  • 主要功能
    • 將多個迭代器的元素打包成元組。
    • 支持不同類型的迭代器。
    • 提供高效的數據處理方式。
  • 使用注意事項
    • 返回的是迭代器,在需要時轉換為串列或其他結構。
    • 當迭代器長度不一致時,以最短的為準。
    • 使用 zip_longest() 處理不同長度的迭代器。

透過掌握 zip() 函數,您可以更高效地處理數據,提高代碼的可讀性和可維護性。


延伸閱讀

Similar Posts