一.切片
本質(zhì)上就是js中的slice方法,只不過表達(dá)形式上有所不同,一樣的是這是一個純函數(shù)
有以下幾種形式
# 使用 [:] 這種形式表示切片
[startIndex=0:endIndex=len(list)]
# 每隔幾個數(shù)取一個值 [::]
[startIndex=0::numToSkip-1]
# 這種情況當(dāng)為-1時,會反向元素 ?。。?小技巧)
# 取區(qū)域內(nèi)的元素,然后每隔幾個取一個
[startIndex=0:endIndex=len(list):numToSkip-1]
具體示例
# 普通的slice
>>> L = list(range(1, 100, 2)) # 即1-100之間的奇數(shù)組成的list
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37,
39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71,
73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]
# 復(fù)制整個list, 直接[:]
>>> anotherList = L[:]
# 復(fù)制部分的list
# 索引為2開始到10(不包含)
>>> partList = L[2:10]
[5, 7, 9, 11, 13, 15, 17, 19]
# 從40開始, 默認(rèn)到最后
>>> partList = L[40:]
[81, 83, 85, 87, 89, 91, 93, 95, 97, 99]
# 默認(rèn)從0開始
>>> partList = L[:10]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
# 從后開始 -1為最后一個
>>> partList = L[-5:-1]
[91, 93, 95, 97]
# 后2個數(shù)
>>> partList = L[-2:]
[97, 99]
# 每隔幾個數(shù)取一個
# 每隔(5 - 1) = 4個取一個
>>> L[::5]
[1, 11, 21, 31, 41, 51, 61, 71, 81, 91]
# 前10個每隔1個取一個
>>> L[:10:2]
[1, 5, 9, 13, 17]
>>> L[3:10:2]
[7, 11, 15, 19]
同樣 tuple 類型 和 str 類型也可以使用切片
>>> (1, 2, 3, 4)[:3]
(1, 2, 3)
>>> s = 'ABCDEFG'
>>> s[:3]
'ABC'
>>> s[::2]
'ACEG'
# 取-1時將字符串反向
>>> s[::-1]
'GFEDCBA'
# [::-2] 則是先反向,然后每隔(2-1)個取一個值
>>> s[::-2]
'GECA'
二.迭代
python中對可迭代對象都可以使用 for...in 進(jìn)行迭代操作
如何判斷一個對象是否可迭代,可以使用python提供的 collections 集合中的 'isinstance' 方法,查看是否屬于 Iterable 的實例
from collections import Iterable
# 對字符串str類型
>>> isinstance('abc', Iterable)
True
# 對list類型
>>> isinstance([1, 2, 3], Iterable)
True
# 對字典dict類型
>>> isinstance({'a': 1, 'b': 2}, Iterable)
True
# 對數(shù)值類型
>>> isinstance(123, Iterable)
False
字典dict 迭代
對于字典類型(dict), 可以使用 items(), values() 方法對值或?qū)嶓w進(jìn)行迭代
>>> d = {'a': 1, 'b': 2, 'c': 3}
# 直接對鍵進(jìn)行迭代
# 因為字典是無序的,所以輸出順序不一定
>>> for key in d:
... print(key)
a
c
b
# 對值進(jìn)行迭代 values()
>>> for value in d.values():
... print(value)
3
2
1
# 對鍵值對進(jìn)行迭代 items()
>>> for k, v in d.items():
... print(k, '', v)
'a' 1
'b' 2
'c' 3
list 帶索引迭代
對于list要將索引也顯示出來,則可以使用python內(nèi)置的 enumerate() 函數(shù)將list變?yōu)?索引-值 對
>>> for i, value in enumerate(['A', 'B', 'C']):
... print(i, value)
0 A
1 B
2 C
字符串str 迭代
>>> for ch in 'ABC':
... print(ch)
A
B
C
for 循環(huán)同時引用2個變量
python中比較常見
>>> for x, y in [(1, 1), (2, 4), (3, 9)]:
... print(x, y)
1 1
2 4
3 9
三.列表生成式 (list comprehensions)
快速生成一個list的簡寫方式
比如要生成一個這樣的list:
[1*1, 2*2, 3*3, 4*4, ..., 10*10]
一般寫法為:
>>> L = []
>>> for x in range(1, 11):
... L.append(x * x)
使用列表生成式,可以寫為:
>>> [x * x for x in range(1, 11)]
將要生成的元素 x*x 放在前面, 后面跟著for循環(huán)即可
還可以在for后面添加條件:
# 只對偶數(shù)平方
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
可以添加2層循環(huán)
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
將dict生成一個list:
>>> d = {'x': 'A', 'y': 'B', 'z': 'C'}
>>> [k + '=' + v for k, v in d.items()]
['y=B', 'x=A', 'z=C']
使用 lower() 方法將列表中的字符串都變?yōu)樾懀?title() 將字符串首字母大寫
>>> L = ['Hello', 18, 'World']
>>> [s.lower() for s in L if isinstance(s, str)]
['hello', 'world']
另外可想而知,轉(zhuǎn)換為大寫的方法為 upper()
四.生成器 generator
好吧,每種語言都是相似的,python中也存在生成器,上面的列表生成式,將'[]' 改為 '()' 即可產(chǎn)生一個generator對象
>>> L = [x * x for x in range(10) if x % 2 == 0]
>>> L
[0, 4, 16, 36, 64]
# 生成一個generator對象
>>> g = (x * x for x in range(10) if x % 2 == 0)
>>> g
<generator object <genexpr> at 0x1022ef630>
生成器的方法 next()
>>> next(g)
0
>>> next(g)
4
>>> next(g)
16
>>> next(g)
36
>>> next(g)
64
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
當(dāng)然我們可以使用 for 循環(huán)來輸出,不用這么麻煩
>>> for n in g:
... print(n)
0
4
16
36
64
在函數(shù)中使用 yield 關(guān)鍵詞,創(chuàng)建generator函數(shù),比如斐波拉契數(shù)列:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n += 1
return 'done'
值得注意的是python的這種賦值的語法,十分的簡潔:
n, a, b = 0, 0, 1
# 還有
a, b = b, a + b
# 相當(dāng)于
a = b
b = a + b
調(diào)用函數(shù)生成一個generator對象:
>>> g = fib(6)
>>> g
<generator object fib at 0x104feaaa0>
使用 for 循環(huán)來輸出
>>> for n in g:
... print(n)
1
1
2
3
5
8
這樣一來就得不到return語句后面的值了(即'done'),如果想要拿到返回值,則必須捕獲StopIteration異常,返回值包含在StopIteration的value中:
>>> g = fib(6)
>>> while True:
... try:
... x = next(g)
... print('g:', x)
... except StopIteration as e:
... print('Generator return value', e.value)
... break
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done
五.Iterable 和 Iterator
可迭代和迭代器是2個不同的概念,其中:
- 集合類型的,如 list, dict, str, 都是Iterable的,但不是Iterator, 凡是可作用于for循環(huán)的對象都是Iterable
- 像generator對象可使用 next() 函數(shù)的都是 Iterator的,同時也是可迭代的Iterable
比如:
from collections import Iterable
# list
>>> isinstance([], Iterable)
True
# dict
>>> isinstance({}, Iterable)
True
# str
>>> isinstance('abc', Iterable)
True
# tuple
>>> isinstance((1, 2, 3), Iterable)
True
# generator
>>> isinstance((x for x in range(10)), Iterable)
True
# 數(shù)值
>>> isinstance(100, Iterable)
False
判斷一個對象是否是 Iterator
from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False
可以使用 iter() 將 list, dict, str 等Iterable變?yōu)?Iterator
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
python中將Iterator對象表示為一個數(shù)據(jù)流,Iterator對象可以被next()函數(shù)調(diào)用并不斷的返回下一個數(shù)據(jù),直到?jīng)]有數(shù)據(jù)拋出 StopIteration 錯誤, Iterator的計算是 惰性的, 可以表示一個無限大的數(shù)據(jù)流
總結(jié)
本章主要將的是一些常用的數(shù)據(jù)操作:
- 切片,和js中的slice類似,只是寫法不同,還有就是可以隔幾個選取1個,稍微有點差異
- 迭代,對集合類型的數(shù)據(jù)進(jìn)行for...in循環(huán), 字典中存在 'values()', 'items()' 等方法, list如果想使用索引,可以使用內(nèi)置的 enumerate() 函數(shù)
- 列表生成式,快速生成一個list的簡便寫法,可以寫二維或以上的for循環(huán),還可以添加條件判斷
- 生成器,這個用來對函數(shù)進(jìn)行控制,快速生成生成器對象的方式和列表生成式比較類似
- 可迭代和迭代器的區(qū)別,以及使用 iter() 將可迭代轉(zhuǎn)換為迭代器
- 異常捕獲使用 try...except ExceptType
- 另外接觸到的函數(shù) lower(), upper(), title()
2017年3月5日 21:55:26