列表生成式
在C語音中,列表的生成一般使用for循環來實現,但在Python中生成一個列表式十分簡單的,簡單的順序列表可以通過range
函數生成,
>>> list(range(1,10))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
但是對於有一定規律的列表,一般都是使用for循環來依次生成,在Python中通過列表生產式可以直接生成複雜的列表。
>>> [x*x*x for x in range(1, 10)]
[1, 8, 27, 64, 125, 216, 343, 512, 729]
還可以進一步增加約束來產生更復雜的序列
>>> [x*x*x for x in range(1, 10) if x % 3 == 0]
[27, 216, 729]
也可以使用多層循環實現多層遍歷或組合
>>> [x + y for x in '1234' for y in '1234' if x != y]
['12', '13', '14', '21', '23', '24', '31', '32', '34', '41', '42', '43']
列表生成器的邏輯與其對應的語句是一致的,如上所示,for x in '1234' for y in '1234'
是循環的範圍,這裏可以通過多個for
實現多層循環的嵌套,x+y
等於循環中執行的語句,if x != y
是最終語句執行的約束條件。遵循這一邏輯,列表生成器可以生成多種不同的list,只要是按照標準for循環可以實現的list,基本都可以使用列表生成器實現。
>>> a="This Is A Test"
>>> [s.lower() for s in a]
['t', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't']
生成器
雖然列表生成式可以直接創建一個我們想要的列表,但是注意到一點,在創建時需要列表的大小是制定的,就是說需要分配一塊指定大小的內存來保存結果。同時在一些情況下,對於具有指定規律的list,我們不需要一個完整的list,只需要在使用時可以獲取對應位置的值即可。因此在Python中,這種一邊循環一邊計算,不需要完全創建一個list的方法就叫做生成器,generator。和列表生辰式的使用方法基本一直,只是使用()來代替[],返回的結果也不是list,而是generator。
>>> g = (x+y for x in range(5) for y in range(5) if x != y)
>>> g
<generator object <genexpr> at 0x7f96a68ae410>
generator也是一個可迭代的數據類型,可以使用for
循環取出對應的值,而且不用擔心出現StopIteration
的錯誤出現。
generator是一個強大的工具,不光能直接在表達式中使用,在函數中也可以使用,來生成更加複雜的有序集合,在函數中通過yield
來將需要的元素輸出的generator
中,如下的例子中生成所有奇數的generator。
def odd():
n = 1
while True:
n = n + 2
yield n
迭代
在Python中,for循環是使用for...in
來完成的,這是一種抽象的for循環遍歷,這種遍歷被稱爲迭代(Iteration).
對於dict的迭代,for key in dict:
是對key的迭代,使用for value in d.value()
來迭代value,使用for k,v in d.items()
來同時迭代key和value。
對於字符串,也可以使用迭代依次取出每個字符。
如果要知道對象是不是可迭代的(Iterable),需要使用導入collections模塊的Iterable類型判斷,isinstance([1,2,3], Iterable)
.
在對list進行迭代時,如果還需要知道對象的下標,則需要使用enumerate
函數,如for i, v in enumerate(['one', 'two', 'three'])
.
對於元素是tuple或list的list,可以直接在迭代是使用多個參數取值,
for x,y in [(1,1), (2,2)]:
print(x,y)
迭代器
一般可以用於for
循環的數據類型,都是可迭代的數據類型,即Iterable
,但他們不是迭代器Iterator
,如list
、tuple
都是Iterable
,而generator
都是Iterator
。因爲迭代器對象指的是一個數據流,它可以通過next
一致取出下一個值,直到StopInteration
的異常拋出,所以可以將迭代器看做是一個有序的序列,但是我們不知道序列的大小,在使用next
取出元素之前,也不能直接得到指定的元素,所以迭代器是惰性
的,它可以指代無限大的序列,如全體整數、自然數或奇數,而list和tuple是有指定大小的數據流,需要在內存中分配指定大小的內存塊。