python推導式和生成器
介紹
1. 列表推導式(List Comprehension)
列表推導式是最常見的一種推導式,它允許你用一行程式碼生成列表,形式如下:
new_list = [expression for item in iterable if condition]
expression
:要新增到新列表的值,可以是簡單的變數,也可以是運算結果。item
:來自迭代物件的每個元素。iterable
:任何可迭代物件(如列表、字串、range 等)。if condition
:可選,用來篩選符合條件的元素。
示例:
生成一個包含平方數的列表:
squares = [x**2 for x in range(10)]
print(squares) # 輸出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
2. 字典推導式(Dictionary Comprehension)
字典推導式與列表推導式類似,只不過它生成的是字典,格式如下:
new_dict = {key: value for item in iterable}
示例:
生成一個鍵為數字,值為其平方的字典:
squares_dict = {x: x**2 for x in range(5)}
print(squares_dict) # 輸出 {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
3. 集合推導式(Set Comprehension)
集合推導式的語法與列表推導式類似,但生成的結果是集合。
new_set = {expression for item in iterable if condition}
示例:
生成一個不重複的平方數集合:
squares_set = {x**2 for x in range(5)}
print(squares_set) # 輸出 {0, 1, 4, 9, 16}
4. 生成器表示式(Generator Expression)
生成器表示式和列表推導式類似,但它不直接生成列表,而是返回一個生成器物件,用於惰性求值,適合處理大量資料。
gen = (x**2 for x in range(10))
print(list(gen)) # 輸出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
5. 巢狀推導式
推導式也可以巢狀,用於生成複雜的結構。
示例:
生成一個二維列表:
matrix = [[i * j for j in range(3)] for i in range(3)]
print(matrix) # 輸出 [[0, 0, 0], [0, 1, 2], [0, 2, 4]]
總結:
推導式使程式碼更加簡潔、可讀,並且在處理生成列表、字典或集合時特別高效。不過,推導式過於複雜時可能會影響程式碼的可讀性,需謹慎使用。
1. 什麼是生成器?
生成器(Generator) 是 Python 中一種特殊型別的迭代器,用於生成一系列的值。在常規的函式中,使用 return
來返回值並結束函式,而在生成器中,使用 yield
來逐次生成值,而不終止函式。生成器可以暫停函式的執行,並在下一次迭代時恢復執行,這種特性使得它適用於處理大量資料或無限資料流。
生成器的定義:
- 生成器可以透過生成器函式建立,使用
yield
語句。 - 生成器也可以透過生成器表示式建立,類似於列表推導式,但使用圓括號代替方括號。
生成器函式示例:
def my_generator():
yield 1
yield 2
yield 3
gen = my_generator()
for value in gen:
print(value)
2. 生成器與列表的區別
-
記憶體佔用:
- 生成器是惰性求值的,這意味著它們不會一次性把所有的值載入到記憶體中,而是每次需要時才生成下一個值,因此非常節省記憶體。
- 列表則會在建立時一次性將所有元素載入到記憶體中,尤其是當資料量很大時,可能導致大量的記憶體佔用。
-
求值方式:
- 生成器是惰性求值的(即在需要時才生成下一個值),而列表是即時求值的(一次性生成整個列表的所有值)。
-
可重複使用:
- 生成器一旦迭代完畢,就不能再次使用,除非重新建立。
- 列表可以多次迭代,因為它們的所有元素都儲存在記憶體中。
列表與生成器的對比:
# 列表
lst = [x**2 for x in range(5)]
print(lst) # 輸出: [0, 1, 4, 9, 16]
# 生成器
gen = (x**2 for x in range(5))
print(list(gen)) # 輸出: [0, 1, 4, 9, 16]
生成器不佔用大量記憶體,但在將生成器轉換為列表時,才會將所有值儲存在記憶體中。
3. 什麼是惰性求值?
惰性求值(Lazy Evaluation),也叫延遲求值,是一種計算策略,指的是當值真正被需要時才進行計算,而不是在定義時立即計算。這使得生成器可以在處理大量資料或無限序列時顯得特別高效。
惰性求值的好處:
- 節省記憶體:生成器不會立即生成所有元素,只在迭代到某個值時才計算它,因此適合處理大規模或無限資料流。
- 提高效率:透過按需生成資料,避免了不必要的計算和記憶體佔用。
示例:
def count_up_to(n):
count = 1
while count <= n:
yield count
count += 1
counter = count_up_to(5)
print(next(counter)) # 1
print(next(counter)) # 2
# 生成器不會計算後續的值,直到你需要它們為止
在此例中,生成器在呼叫 next()
時才生成下一個值,未被呼叫時不會生成,因此更高效。
總結:
- 生成器是惰性求值的迭代器,用來節省記憶體並延遲計算。
- 列表是立即求值的,它會一次性載入所有元素。
- 惰性求值是指在需要時才進行計算,而不是立即執行,從而提高效能和記憶體使用效率。
生成器特別適用於大規模或無限序列的處理場景,因為它們僅在需要時生成資料,非常節省記憶體。