1.list列表
Python內(nèi)置一種數(shù)據(jù)結(jié)構(gòu)list举瑰。
- classmates = ['Micle', 'Tom', 'Tonny']
- len(classmates)獲得list的元素個數(shù)
- 索引訪問list中的元素calssmates[0]
- 取最后一個元素classmates[-1],倒數(shù)第二個classmates[-2]
- list是一個可變的有序表刃唤,可以末尾追加元素classmates.append('Adam')
- 插入到指定位置classmates.insert(1,'Jack')
- 刪除末尾元素classmates.pop()元暴,刪除指定位置元素classmates.pop(1)
- 若要替換其中元素防嗡,直接向索引位置賦值
2. tuple元組
Python內(nèi)置另一種有序列表
1.一旦初始化以后就不可修改classmates = ( 'Micle', 'Tom', 'Tonny')琼富。
可以讀取元素雌贱,但是無法賦值或者修改凛虽。這樣數(shù)據(jù)更安全死遭,所以推薦使用。
- 可變tuple:t = ('a', 'b', ['A', 'B'])凯旋,此時可以修改其中的list值
3. dict字典
使用鍵-值存儲殃姓,具有極快的查找速度
- d = {'Micle':95, 'Tom':75, 'Tonny':85}
>>>d['Micle']
95 - 為了避免key不存在的情況,用in或get()判斷
>>>'Tomas' in d
False
>>>d.get('Tomas')瓦阐,不存在可以返回None蜗侈,此時不顯示結(jié)果
>>>d.get('Tomas',-1),自己設(shè)定返回值 - 和list比較睡蟋,dict有以下幾個特點:
查找和插入的速度極快踏幻,不會隨著key的增加而變慢;
需要占用大量的內(nèi)存戳杀,內(nèi)存浪費多该面。
而list相反:
查找和插入的時間隨著元素的增加而增加;
占用空間小信卡,浪費內(nèi)存很少隔缀。
所以,dict是用空間來換取時間的一種方法傍菇。
4.set集合
set和dict類似猾瘸,也是一組key的集合,但不存儲value丢习。由于key不能重復(fù)牵触,所以,在set中咐低,沒有重復(fù)的key揽思。
- 要創(chuàng)建一個set,需要提供一個list作為輸入集合:
>>> s = set([1, 2, 3])
>>> s
{1, 2, 3} - 重復(fù)元素在set中自動被過濾
- 通過add(key)方法可以添加元素到set中见擦,可以重復(fù)添加钉汗,但不會有效果:
- 通過remove(key)方法可以刪除元素:
- set可以看成數(shù)學(xué)意義上的無序和無重復(fù)元素的集合羹令,因此,兩個set可以做數(shù)學(xué)意義上的交集损痰、并集等操作:
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}
5.列表生成式
列表生成式即List Comprehensions特恬,是Python內(nèi)置的非常簡單卻強大的可以用來創(chuàng)建list的生成式。
- 列表生成式則可以用一行語句代替循環(huán)生成list:
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
寫列表生成式時徐钠,把要生成的元素x * x放到前面癌刽,后面跟for循環(huán),就可以把list創(chuàng)建出來. - for循環(huán)后面還可以加上if判斷尝丐,這樣我們就可以篩選出僅偶數(shù)的平方:
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
還可以使用兩層循環(huán)显拜,可以生成全排列:
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
6.生成器generator
- 要創(chuàng)建一個generator,有很多種方法爹袁。第一種方法很簡單远荠,只要把一個列表生成式的[]改成(),就創(chuàng)建了一個generator:
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
創(chuàng)建L和g的區(qū)別僅在于最外層的[]和()失息,L是一個list譬淳,而g是一個generator。 - 如果要一個一個打印出來盹兢,可以通過next()函數(shù)獲得generator的下一個返回值:
>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
不斷調(diào)用next(g)實在是太變態(tài)了邻梆,正確的方法是使用for循環(huán),因為generator也是可迭代對象:
>>> g = (x * x for x in range(10))
>>> for n in g:
... print(n) - 如果推算的算法比較復(fù)雜绎秒,用類似列表生成式的for循環(huán)無法實現(xiàn)的時候浦妄,還可以用函數(shù)來實現(xiàn)。
要把fib函數(shù)變成generator见芹,只需要把print(b)改為yield b就可以了:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
這就是定義generator的另一種方法剂娄。如果一個函數(shù)定義中包含yield關(guān)鍵字,那么這個函數(shù)就不再是一個普通函數(shù)玄呛,而是一個generator:
7. 迭代器
我們已經(jīng)知道阅懦,可以直接作用于for循環(huán)的數(shù)據(jù)類型有以下幾種:
一類是集合數(shù)據(jù)類型,如list徘铝、tuple耳胎、dict、set庭砍、str等场晶;
一類是generator,包括生成器和帶yield的generator function怠缸。
- 這些可以直接作用于for循環(huán)的對象統(tǒng)稱為可迭代對象:Iterable。
可以使用isinstance()判斷一個對象是否是Iterable對象:
>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True - 可以被next()函數(shù)調(diào)用并不斷返回下一個值的對象稱為迭代器:Iterator钳宪。
可以使用isinstance()判斷一個對象是否是Iterator對象:
>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True - 生成器都是Iterator對象揭北,但list扳炬、dict、str雖然是Iterable搔体,卻不是Iterator恨樟。
把list、dict疚俱、str等Iterable變成Iterator可以使用iter()函數(shù):
8. map()函數(shù)與reduce()函數(shù)
map()函數(shù)接收兩個參數(shù)劝术,一個是函數(shù),一個是Iterator呆奕,map將傳入的函數(shù)依次作用到序列的每個元素养晋,并把結(jié)果作為新的Iterator返回。
reduce()把一個函數(shù)作用在一個序列[x1, x2, x3, ...]上梁钾,這個函數(shù)必須接收兩個參數(shù)绳泉,reduce把結(jié)果繼續(xù)和序列的下一個元素做累積計算
9. filter()函數(shù)
和map()類似,filter()也接收一個函數(shù)和一個序列姆泻。和map()不同的是零酪,filter()把傳入的函數(shù)依次作用于每個元素,然后根據(jù)返回值是True還是False決定保留還是丟棄該元素拇勃。
例如四苇,在一個list中,刪掉偶數(shù)方咆,只保留奇數(shù)蛔琅,可以這么寫:
def is_odd(n):
return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 結(jié)果: [1, 5, 9, 15]
10. sorted()函數(shù)
- Python內(nèi)置的sorted()函數(shù)就可以對list進行排序:
>>> sorted([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36] - 此外,sorted()函數(shù)也是一個高階函數(shù)峻呛,它還可以接收一個key函數(shù)來實現(xiàn)自定義的排序罗售,例如按絕對值大小排序:
>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
key指定的函數(shù)將作用于list的每一個元素上,并根據(jù)key函數(shù)返回的結(jié)果進行排序钩述。 - 要進行反向排序寨躁,不必改動key函數(shù),可以傳入第三個參數(shù)reverse=True:
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']
11.匿名函數(shù)lambda
當(dāng)我們在傳入函數(shù)時牙勘,有些時候职恳,不需要顯式地定義函數(shù),直接傳入匿名函數(shù)更方便方面。
- 匿名函數(shù)lambda x: x * x實際上就是:
def f(x):
return x * x
關(guān)鍵字lambda表示匿名函數(shù)放钦,冒號前面的x表示函數(shù)參數(shù)。
匿名函數(shù)有個限制恭金,就是只能有一個表達式操禀,不用寫return,返回值就是該表達式的結(jié)果横腿。
- 用匿名函數(shù)有個好處颓屑,因為函數(shù)沒有名字斤寂,不必?fù)?dān)心函數(shù)名沖突。此外揪惦,匿名函數(shù)也是一個函數(shù)對象遍搞,也可以把匿名函數(shù)賦值給一個變量,再利用變量來調(diào)用該函數(shù):
>>> f = lambda x: x * x
>>> f
<function <lambda> at 0x101c6ef28>
>>> f(5)
25 - 同樣器腋,也可以把匿名函數(shù)作為返回值返回溪猿,比如:
def build(x, y):
return lambda: x * x + y * y
PS
- 賦值語句:
a, b = b, a + b
相當(dāng)于:
t = (b, a + b) # t是一個tuple
a = t[0]
b = t[1]
但不必顯式寫出臨時變量t就可以賦值。`