python 生成器、列表/字典/集合解析式區別

一、列表解析

列表解析也叫列表推導式,是python編程中常用到的語法糖。列表推導是一個將一個列表(實際上是任意可迭代對象)轉換成另一個列表的工具。在轉換時,每個元素都可以按照某個條件被包含在新的列表中,並根據需要做出一些變換。

先看一例子,比如我想把某列表中的每項值都乘以2

# 迭代列表for方法
nlist = range(5)	# 用range內置函數快速生成列表[0, 1, 2, 3, 4]
mlist = list()	# 創建新的空列表對象
for i in nlist:
    mlist.append(i)
print mlist
[0, 2, 4, 6, 8]

# 利用列表推導式,只需一行代碼,6得不行,python就那麼屌
mlist = [i * 2 for i in range(5)]
print mlist
[0, 2, 4, 6, 8]

列表推導式結合if關鍵字可以爲我們做一些過濾

# 過濾掉列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]中值爲奇數的項
lst = [i for i in range(11) if i % 2 == 0]
print lst
[0, 2, 4, 6, 8, 10]

列表推導式的嵌套循環

# [[1, 2, 3], [4, 5, 6]] --> [1, 2, 3, 4, 5, 6]
nlist =  [[1, 2, 3], [4, 5, 6]]
lst = [i for item in nlist for i in item]
print list
[1, 2, 3, 4, 5, 6]

列表推導式是不是很6很屌啊 ~~
注: 內置的map函數調用比等效的for循環要快兩倍,而列表解析往往比map調用要快

二、字典解析

字典的形式是: {key: val},所以字典解析式也是用花括號括起來的

# 快速生成值是鍵二倍的字典
ndict = {x: x*2 for x in range(5)}
print ndict
{0: 0, 1: 2, 2: 4, 3: 6, 4: 8}

三、集合解析

python中集合也是用花括號括起來的,所以集合解析式: {x for x in iter}

# 快速生成1-10的集合
nset = {x for x in range(1, 11)}
print nset
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

四、生成器

1、何爲生成器

和返回一個值並退出的常規函數不同,生成器是可以從其退出的地方繼續的函數。用到的關鍵字:yield

2、生成器函數應用
def test(num):
	for i in range(num):
        a = yield i * 2
        print a

g = test(5)
g
<generator object test at 0x7f2e24449d70i>
next(g)
0
next(g)
2
next(g)
4
next(g)
8
next(g)
StopIteration ... # 已迭代完,繼續迭代所以拋異常

下面我們看看生成器函數的協議:sendnext

def test(num):
	for i in range(num):
        a = yield i * 2
        if a == 22:
        	print '剪刀手最2...'
        print a

x = test(5)
next(x)
0
x.send(11)
11
1
x.send(22)
剪刀手最2…
2
next(x)
3

用send方法,編寫一個能夠被它的調用着終止的生成器。

3、生成器表達式

類似列表推導式,但用的的圓括號:()

g = (x * 2 for x in range(5))
g
<generator object <genexpr> at 0x7f2e1e80a410>
next(g)
0
next(g)
1

注: 生成器是單迭代器對象

g = gg = (x * 2 for x in range(5))
next(g)
0
next(g)
1
next(gg)
2

4、生成器 VS 列表推導式

列表推導式是一次性創建所有數據的,而生成器是生成對象,需要我們調用next方法逐一獲取元素。假設我創建的數據很大很大(比如一千萬),列表推導式會一次性創建,需要分配很大的內存空間存放這一千萬數據,而生成器不會,只是創建了一個生成器對象,所以生成器更節省內存

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章