1. 切片
對經常取指定索引範圍的操作,用循環十分繁瑣,因此,Python提供了切片(Slice)操作符,能大大簡化這種操作。
L[0:3]表示,從索引0
開始取,直到索引3
爲止,但不包括索引3
。即索引0
,1
,2
,正好是3個元素
如果第一個索引是0
,還可以省略
類似的,既然Python支持L[-1]
取倒數第一個元素,那麼它同樣支持倒數切片
>>> L= ['Alice','Bob','Clilly','Donna','Frank']
>>> L[0:3]
['Alice', 'Bob', 'Clilly']
>>> L[:3]
['Alice', 'Bob', 'Clilly']
>>> L[1:3]
['Bob', 'Clilly']
>>> L[-2:]
['Donna', 'Frank']
>>>
什麼都不寫就是複製了一個list
tuple也是一種list,唯一區別是tuple不可變。因此,tuple也可以用切片操作,只是操作的結果仍是tuple
字符串'xxx'
也可以看成是一種list,每個元素就是一個字符。因此,字符串也可以用切片操作,只是操作結果仍是字符串:
Practice: 利用切片操作,實現一個trim()函數,去除字符串首尾空格
>>> def trim(s):
while s[:1]==" ":
s=s[1:]
while s[-1:]==" ":
s=s[:-1]
return s
>>> trim(' hello ')
'hello'
>>> trim('joke ')
'joke'
>>>
2.迭代
如果給定一個list或tuple,我們可以通過for循環來遍歷這個list或tuple,這種遍歷我們稱之爲迭代(Iteration)
在Python中,迭代式通過for ...in 來完成的
>>> d = {'a':1, 'b':2, 'c':3}
>>> for key in d:
print(key)
a
b
c
默認情況下,dict迭代的是key,如果要迭代value,可以用 for value in d.values()
如果要同時迭代key和value,可以用for k, v in d.items()
>>> for key,value in d.items():
print(key, value)
a 1
b 2
c 3
>>>
字符串也是可迭代對象,因此,也可以作爲for循環:
>>> for ch in 'ABC':
print(ch)
A
B
C
>>>
所以,當我們使用for循環時,只要作用於一個可迭代對象,for循環就可以正常運行,而我們不太關心該對象究竟是list還是其他數據類型。
可以通過collections模塊的iterable類型判斷:
>>> from collections import Iterable
>>> isinstance('abc', Iterable)
True
>>> isinstance([1,2,3], Iterable)
True
>>> isinstance(123, Iterable)
False
>>>
如果要對list實現類似Java那樣的下標循環怎麼辦?Python內置的enumerate函數可以把一個list變成索引-元素對,這樣就可以在for循環中同時迭代索引和元素本身:
>>> for i, value in enumerate(['A', 'B', 'C']):
print(i, value)
0 A
1 B
2 C
>>>
同時引用兩個變量,在Python裏也是很常見的:
>>> for x, y in [(1,1), (2,4), (3,9)]:
print(x,y)
1 1
2 4
3 9
>>>
Practice: 使用迭代查找list中的最大值和最小值,並返回一個tuple:
>>> def findMinAndMax(L):
if len(L)==0:
return(None, None)
else:
max = L[0]
min = L[0]
for s in L:
if s>max:
max =s
if s<min:
min=s
return(min,max)
>>> findMinAndMax([8,0,9,7])
(0, 9)
>>> findMinAndMax([])
(None, None)
>>> findMinAndMax([9])
(9, 9)
>>>
3. 列表生成式
要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
可以用list(range(1, 11))
:
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
生成[1x1, 2x2, 3x3, ..., 10x10]
怎麼做
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
篩選出僅偶數的平方
>>> [x*x for x in range(1,11) if x%2==0]
[4, 16, 36, 64, 100]
使用兩層循環,可以生成全排列
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
列出當前目錄下的所有文件和目錄名,可以通過一行代碼實現
>>> import os>>> [d for d in os.listdir('.')]
['df.py', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'ls.py', 'NEWS.txt', 'python.exe', 'python3.dll', 'python36.dll', 'pythonw.exe', 'Scripts', 'tcl', 'Tools', 'vcruntime140.dll']
>>> for 循環
可以同時使用來兩個甚至多個變量,比如dict的items()
4. 生成器
在Python中一邊循環一邊計算的機制稱爲生成器:generator
>>> g =(x*x for x in range(10))
>>> for n in g:
print(n)
0
1
4
9
16
25
36
49
64
81
>>>
斐波那契數列:
函數實現:
>>> def fib(max):
n,a,b=0,0,1
while n<max:
print(b)
a, b=b , a+b
n=n+1
return 'done'
>>> fib(6)
1
1
2
3
5
8
'done'
>>>
生成器實現:
>>> def fib(max):
n,a,b =0,0,1
while n<max:
yield b
a,b=b,a+b
n=n+1
return 'done'
>>> for n in fib(6):
print(n)
1
1
2
3
5
8
>>>
generator是非常強大的工具,在Python中可以簡單地把列表生成式改成generator,也可以通過函數實現複雜邏輯的generator。
要理解generator的工作原理,它是在for循環的過程中不斷計算出下一個元素,並在適當的條件結束for循環。對於函數改成generator來說,遇到return語句或者執行到函數體最後一行語句,就是結束generator的指令,for循環隨之結束。
區分普通函數和generator、函數,普通函數直接返回結果,generator函數的“調用”實際返回一個generator對象:
>>> r = abs(6)
>>> r
6
>>> g = fib(6)
>>> g
<generator object fib at 0x06042ED0>
>>>
Practice:用generator輸出楊輝三角:
1
/ \
1 1
/ \ / \
1 2 1
/ \ / \ / \
1 3 3 1
/ \ / \ / \ / \
1 4 6 4 1
/ \ / \ / \ / \ / \
1 5 10 10 5 1
>>> def triangles():
n=0
L=[1]
while n<10:
yield L
L = [1]+[L[i]+L[i+1] for i in range(n)]+[1]
n=n+1
>>> for i in triangles():
print(i)
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
>>>
5. 迭代器
我們已經知道,可以直接作用於for
循環的數據類型有以下幾種:
一類是集合數據類型,如list
、tuple
、dict
、set
、str
等;
一類是generator
,包括生成器和帶yield
的generator function。
這些可以直接作用於for
循環的對象統稱爲可迭代對象:Iterable
。
可以使用isinstance()
判斷一個對象是否是Iterable
對象:
而生成器不但可以作用於for
循環,還可以被next()
函數不斷調用並返回下一個值,直到最後拋出StopIteration
錯誤表示無法繼續返回下一個值了。
可以被next()
函數調用並不斷返回下一個值的對象稱爲迭代器:Iterator
。
凡是可作用於for
循環的對象都是Iterable
類型;
凡是可作用於next()
函數的對象都是Iterator
類型,它們表示一個惰性計算的序列;
集合數據類型如list
、dict
、str
等是Iterable
但不是Iterator
,不過可以通過iter()
函數獲得一個Iterator
對象。