day11- python生成式和生成器
列表生成式
列表生成式是python受歡迎的語法之一,通過一句簡潔的語法就可以對一組元素進行過濾,還可以對得到的元素進行轉換處理。語法格式為:
[exp for val in collection if condition]
相當於
result=[]
for val in collection:
if(condition):
result.append(exp)
例子:
#!/usr/bin/env python # -*- coding:utf-8 -*- # @time: 2017/11/5 21:20 # Author: caicai # @File: demon9.py #列表生產式 li = [x*x for x in range(1,101) if x%2==0] print(li) #普通函數 def funa(): a = [] for x in range(1,100): if x%2 == 0: a.append(x*x) return a print(funa()) 輸出結果一致
解釋:
1, 以此取出xrange(10)從0到9的數字
2, 判斷x*x是偶數,就保留,存在新的字典中
3, 把所有符合x*x是偶數的元素都放到新的列表中返回
通過列表生成式,我們可以直接創建一個列表。但是,受到內存限制,列表容量肯定是有限的。而且,創建一個包含100萬個元素的列表,不僅占用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那後面絕大多數元素占用的空間都白白浪費了。
所以,如果列表元素可以按照某種算法推算出來,那我們是否可以在循環的過程中不斷推算出後續的元素呢?這樣就不必創建完整的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,稱為生成器(Generator)。
要創建一個generator,有很多種方法。第一種方法是把一個列表生成式的[]改成(),就創建了一個generator:
例子:
# 列表生成器 #1.最簡單的辦法,把原來的生成式的[]換成()就ok lt = (x*x for x in range(1,101) if x%2==0) print(lt) print(lt.__next__()) print(lt.__next__()) print(lt.__next__()) for i in lt: print(i)
2、定義generator的另一種方法。如果一個函數定義中包含yield關鍵字,那麽這個函數就不再是一個普通函數,而是一個generator:
例子:
#2.函數中定義列表生成器 print(‘##############第二種方法##############‘) def fib(n): sum = 0 i = 0 while(i<n): sum = sum + i i+=1 yield(sum) print(type(fib(10))) for x in fib(10): print(x) #列表生產式:一次性生成所有的數據,然後保存在內存中,適合小量的數據, #生成器:返回一個可叠代的對象,以及‘generator’對象,必須通過循環才可以一一列出所有的結果 #可叠代對象:可以通過循環調用出來的,就是可叠代對象,如列表,元組,字典,生產式 #叠代器:簡單理解為生成器,必須通過next()函數調用並不斷返回下一個值的對象稱為叠代器。
生成式和生成器二者的區別很明顯:
一個直接返回了表達式的結果列表, 而另一個是一個對象,該對象包含了對表達式結果的計算引用, 通過循環可以直接輸出
生成器不會一次性列出所有的數據,當你用到的時候,在列出來,更加節約內存的使用率。
叠代器
Iterable(可叠代對象) 和 Iterator(叠代器) 主要區別是 :
凡是可以用 for 循環的 都是 Iterable(可叠代對象) 凡是需要通過next()函數獲得值的可叠代對象都是 Iterator(叠代器)。
(所以生成器可以 被next()函數調用並不斷返回下一個值的對象稱為叠代器 ) (可以簡單理解為生成器 就是 叠代器的可叠代對象)
凡是可作用於for循環的對象都是Iterable類型;
凡是可作用於next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列;
學習例子
函數表示9*9乘法口訣 def pro(): for i in range(1,10): for j in range(1,i+1): print("%d*%d=%d\t" %(j,i,j*i)), print("\n") print(pro())
day11- python生成式和生成器