python快速上手_第四章 列表
列表資料型別
Python 中的列表,與 java中的 陣列比較像。[] 包含, 以 “,”分隔, 通過下標取元素,下標以 0 開始。
列表是一個值, 它包含多個值構成的序列。
>>> [1,2,3] [1, 2, 3] >>> ['cat','bat','rat','elephant'] ['cat', 'bat', 'rat', 'elephant'] >>> ['hello',3.1415,True,None,42] ['hello', 3.1415, True, None, 42] >>> spam = ['cat','bat','rat','elephant'] >>> spam ['cat', 'bat', 'rat', 'elephant']
用下標取得列表中的單個值
和java中陣列的取值方式相同,而且 下標也是從 0 開始。
>>> spam = ['cat','bat','rat','elephant'] >>> spam ['cat', 'bat', 'rat', 'elephant'] >>> spam[0] 'cat' >>> spam[1] 'bat' >>> 'Helllo'+spam[0] 'Helllocat' >>> 'The ' +spam[1] + ' ate the '+spam[0] 'The bat ate the cat'
如果下標超出列表中的個數。Python將給出 IndexError 出錯資訊。
>>> spam[10]
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
spam[10]
IndexError: list index out of range
下標超出範圍
列表中也可以包含其他的列表,類似java中的 多元陣列
>>> spam = [['cat','bat'],[10,20,30,40,50]] >>> spam[0][1] 'bat' >>> spam[1][2] 30
負數下標
也可以用負整數來作為下標。整數值 -1 指的是列表中的最後一個下標; -2指的是列表中的倒數第二個下標,以此類推
>>> spam = ['a','b','c','d']
>>> spam[-1]
'd'
>>> spam[-2]
'c'
利用切片取得子列表
“切片“ 可以從列表中取得多個值,結果是一個新列表。
spam[1:4] 是一個列表和切片
第一個整數是切片開始處的下標,第二個整數是切片結束處的下標。包前不包後。結果為一個新的列表。
>>> spam = ['a','b','c','d']
>>> spam[-1]
'd'
>>> spam[-2]
'c'
>>> spam
['a', 'b', 'c', 'd']
>>> spam[0:4]
['a', 'b', 'c', 'd']
>>> spam[1:3]
['b', 'c']
>>> spam[0:5]
['a', 'b', 'c', 'd']
>>> spam[0:10]
['a', 'b', 'c', 'd']
>>> spam[-1:2]
[]
省略第一個整數, 代表從 0 開始,或者列表的開始。 省略第二個整數 代表 到列表的結束。
>>> spam = ['cat','bat','rat','elephant']
>>> spam
['cat', 'bat', 'rat', 'elephant']
>>> spam[:2]
['cat', 'bat']
>>> spam[1:]
['bat', 'rat', 'elephant']
>>> spam[:]
['cat', 'bat', 'rat', 'elephant']
len 取得列表的長度
len()函式 將返回傳遞給它的列表的值的個數。
>>> spam
['cat', 'bat', 'rat', 'elephant']
>>> len(spam)
4
用下標來改變列表中的值
可以使用列表的下標來改變下標處的值。
>>> spam
['cat', 'bat', 'rat', 'elephant']
>>> spam[1] = 'dog'
>>> spam
['cat', 'dog', 'rat', 'elephant']
>>> spam[2] = spam[1]
>>> spam
['cat', 'dog', 'dog', 'elephant']
>>> spam[-1] = 123
>>> spam
['cat', 'dog', 'dog', 123]
列表的拼接和複製
可以使用 + 符號來連線兩個列表,就如同連線兩個字串那樣。
使用 一個 列表 和 * 符號來實現複製列表的功能。
>>> [1,2,3] + ['A','B','C','D']
[1, 2, 3, 'A', 'B', 'C', 'D']
>>> [1,2,3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> spam = ['d','e','f']
>>> spam + ['A','B']
['d', 'e', 'f', 'A', 'B']
使用 del 來刪除列表中的值
使用del來刪除指定列表下的值,刪除後,該下標後面的元素都向前移動一個下標。
>>> spam
['d', 'e', 'f']
>>> del spam[0]
>>> spam
['e', 'f']
>>> del spam[1]
>>> spam
['e']
>>> del spam[-1]
>>> spam
[]
使用列表
之前,我們說到了用變數來儲存資料。 但是,如果資料量大了呢? 就會出現大量的變數,重複的內容。而且新增等操作起來極其麻煩,還得再增加程式碼。
我們可以使用列表來儲存這些相似的資料。 比如以下:
catNames = []
while True:
print('Enter the name of cat '+str(len(catNames) + 1) + ' (Or enter nothing to stop.)')
name = input()
if name =='':
break
catNames = catNames+[name]
print('The cat names are : ')
for name in catNames:
print(' '+name)
列表用於迴圈
for i in range(4):
print(i)
0
1
2
3
range(4) 的返回值類似列表的值,python認為它類似於[0,1,2,3].
讓變數依次設定為 列表中的值。
一個比較常見的技巧是在 for 迴圈中使用 range(len(somelist)) 獲取到每一個下標,然後可以通過 somelist[index]的方式,獲取到每一個值。
兩種遍歷方式如下:
>>> supplies = ['pens','staplers','binders','rulers']
>>> for i in supplies:
print('Index '+i)
Index pens
Index staplers
Index binders
Index rulers
>>> for i in range(len(supplies)):
print('Index : '+str(i) + ' in supplies is : '+supplies[i])
Index : 0 in supplies is : pens
Index : 1 in supplies is : staplers
Index : 2 in supplies is : binders
Index : 3 in supplies is : rulers
in和not in 操作符
in 和 not in 類似於 java 中的 contians 。 判斷一個值是否在一個列表中, 如果存在,則返回True ; 否則返回false.
>>> 'a' in ['a','b','c']
True
>>> 'a' not in ['a','b','c']
False
>>> letters = ['a','b','c']
>>> 'b' not in letters
False
下面的例子來判斷,寵物是否在列表中:
myPets = ['Zophie','Pooka','Fat']
print('Enter a pet Name : ')
name = input()
if name in myPets:
print(name + ' is my pet ')
else:
print('I do not have a pet Named : '+name )
多重賦值技巧
是一種快捷的賦值方式, 用列表中的值為變數賦值; 要求列表中的值個數 和 變數的個數相同。 否則會報出 ValueError的錯誤.
>>> cat = ['fat','black','loud']
>>> size = cat[0]
>>> color = cat[1]
>>> disposition = cat[2]
>>> size
'fat'
>>>
>>> size,color,disposition = cat
>>> color
'black'
當列表的值的個數和變數個數不用的時候:
>>> size,color = cat
Traceback (most recent call last):
File "<pyshell#82>", line 1, in <module>
size,color = cat
ValueError: too many values to unpack (expected 2)
增強的賦值操作
>>> spam = 42
>>> spam = spam + 1
>>> spam
43
上面的賦值操作,可以替換為:
>>> spam = 42
>>> spam += 1
>>> spam
43
用 += 來完成同樣的事情。
針對 + - * / % 操作符, 都有增強操作符。
spam += 1 spam = spam+1
spam -= 1 spam = spam-1
spam *= 1 spam = spam*1
spam /= 1 spam = spam/1
spam %= 1 spam = spam%1
+= 操作符同樣可用於字串, *=操作符同樣可用於 字串和列表的複製
>>> spam = 'hello '
>>> spam+='world'
>>> spam
'hello world'
>>> bacon = ['abc']
>>> bacon*=3
>>> bacon
['abc', 'abc', 'abc']
方法
方法和函式其實是一回事,只是方法呼叫在一個值上。比如 java中對於字串操作的 substring()、split()等, 在python中也是一樣的操作方式。
用index()方法在列表中查詢值
index() 方法傳入一個值, 如果該值在列表中,就返回該值的下標.如果不存在,則會報錯。
>>> spam = ['hello','world','abc']
>>> spam.index('hello')
0
>>> spam.index('abc')
2
>>> spam.index('def')
Traceback (most recent call last):
File "<pyshell#107>", line 1, in <module>
spam.index('def')
ValueError: 'def' is not in list
如果列表中有重複的值,就返回第一次出現的下標。
>>> spam = ['a','b','d','a','a']
>>> spam.index('a')
0
用append 和 insert 方法在列表中新增值
在列表中新增新值.使用append() 和 insert方法。
>>> spam = ['hello','world','ni']
>>> spam.append('hao')
>>> spam
['hello', 'world', 'ni', 'hao']
append()方法時在列表的後面新增一個值, 而 insert 是在列表的任意位置新增一個值。
>>> spam = ['hello','ni']
>>> spam.insert(1,'world')
>>> spam
['hello', 'world', 'ni']
>>> spam.insert(2,'world')
>>> spam
['hello', 'world', 'world', 'ni']
>>> spam.insert(4,'hao')
>>> spam
['hello', 'world', 'world', 'ni', 'hao']
append()和insert() 都是列表方法,不能在其他的值上面呼叫
>>> spam = 'Hello'
>>> spam.append(' World')
Traceback (most recent call last):
File "<pyshell#134>", line 1, in <module>
spam.append(' World')
AttributeError: 'str' object has no attribute 'append'
用remove方法移除列表中的值
往remove()方法中傳遞一個值, 將試圖從列表中刪除,如果存在則刪除,如果不存在 則報錯 ValueError.
>>> spam = ['cat','dog','snake','mouse']
>>> spam.remove('cat')
>>> spam
['dog', 'snake', 'mouse']
>>> spam.remove('elephant')
Traceback (most recent call last):
File "<pyshell#141>", line 1, in <module>
spam.remove('elephant')
ValueError: list.remove(x): x not in list
如果列表中有多個相同的值,那麼只有第一次出現的值才會被刪除。
>>> spam = ['a','b','a','c']
>>> spam.remove('a')
>>> spam
['b', 'a', 'c']
刪除有兩種方法:
- del,在知道要刪除值的下標的情況下。
- remove,在知道要刪除的值的情況下。
>>> spam
['b', 'a', 'c']
>>> del(spam[1])
>>> spam
['b', 'c']
用 sort()方法將列表中的值排序
數值的列表 和 字串的列表,可以用 sort()排序, 也可以指定 reverse 關鍵字引數為True,讓 sort 按逆序排序
>>> spam = [3,2,-1,10,28,12,15]
>>> spam.sort()
>>> spam
[-1, 2, 3, 10, 12, 15, 28]
>>>
>>> spam = ['hello','Alice','Eirc','Bob']
>>> spam.sort
<built-in method sort of list object at 0x112146988>
>>> spam.sort()
>>> spam
['Alice', 'Bob', 'Eirc', 'hello']
逆序排序
>>> spam.sort(reverse = True)
>>> spam
['hello', 'Eirc', 'Bob', 'Alice']
用sort方法排序,需要注意一下幾點:
- sort()方法當場對列表排序,不要寫出 spam = spam.sort()這樣的程式碼。
- 不能對既有數字又有字串的列表排序,因為python不知道如何比較他們。(示例見下面)
- sort()方法對字元排序時,使用的是‘ASCII字元順序’,而不是實際的字典順序。以為著大寫字母排在小寫字母之前。如果需要按字典順序來排序的話,可以給 sort方法指定關鍵字引數 key 設定為 str.lower。排序的時候會把所有的字母當成小寫,而並不會實際改變列表中的值。
第二條 示例:
>>> spam = ['a','b',1,2,'c']
>>> spam.sort()
Traceback (most recent call last):
File "<pyshell#169>", line 1, in <module>
spam.sort()
TypeError: '<' not supported between instances of 'int' and 'str'
第三條 示例:
>>> spam = ['a','C','Z','b','E']
>>> spam.sort()
>>> spam
['C', 'E', 'Z', 'a', 'b']
>>> spam.sort(key = str.lower)
>>> spam
['a', 'b', 'C', 'E', 'Z']
神奇8球
# magic8Ball2 program
import random
messages = ['First','Second','Third','Fourth','FiFth','Sixth','Seventh']
print(messages[random.randint(1,len(messages)-1)])
在列表中儲存了我們的資料, 然後生成隨機數,獲取對於的數值並列印。
python中的縮排規則的例外
多數情況下,程式碼行的縮排告訴python它屬於哪個程式碼塊。但是有幾個例外。
1.在原始碼檔案中,列表可以跨越幾行,這些行的縮排並不重要。python認為沒有看到方括號,列表就沒有結束。
spam = ['a',
'b',
'c']
print(spam)
2.也可以在行末使用續行字元 \ .將一條指令寫成多行。可以把 “\” 看成是“這條指令在下一行繼續”。
print('hello'+\
'world')
類似列表的資料型別:字串和元組
字串和列表很相似, 可以認為字串是單個文字字元的列表。 很多用於列表的操作,都可以用於字串: 按下標取值、切片、for迴圈、用於len(),以及in和not in操作符。
>>> name = 'helloworld'
>>> name[0]
'h'
>>> name[-2]
'l'
>>> name[0:4]
'hell'
>>> 'wo' in name
True
>>> 'or' in name
True
>>> 'cd' in name
False
>>> for i in name:
print('........'+i +'........')
........h........
........e........
........l........
........l........
........o........
........w........
........o........
........r........
........l........
........d........
可變和不可變資料型別。
列表是可變的,字串是不可變的。 這裡和java中的有些類似,java中的字串也是不可變的;但可以重新賦值一個新的字串。
>>> name = 'Hello a world'
>>> name[6] = 'abc'
Traceback (most recent call last):
File "<pyshell#197>", line 1, in <module>
name[6] = 'abc'
TypeError: 'str' object does not support item assignment
因為字串是不可變的,所以會報錯。可以通過下面的方式來建立一個新的字串:
>>> name
'Hello a world'
>>> newName = name[0:6] + 'abc'+name[7:]
>>> newName
'Hello abc world'
列表值時可變的,但對於下面的程式碼,卻並沒有修改列表,只是重新賦值,覆寫了列表。
>>> eggs = [1,2,3]
>>> eggs = [4,5,6]
>>> eggs
[4, 5, 6]
如果確實想修改列表,可以通過列表的方法來操作, 比如 append,remove,del等等。
>>> eggs = [1,2,3]
>>> eggs.remove(1)
>>> eggs
[2, 3]
>>> eggs.append(4)
>>> eggs
[2, 3, 4]
>>> del eggs[0]
>>> eggs
[3, 4]
>>> eggs.insert(0,5)
>>> eggs
[5, 3, 4]
元組資料型別
元組資料型別和列表資料型別幾乎一樣。
不同點在於:
- 元組輸入用(),列表用[]
>>> eggs = ('hello','world',21,31)
>>> eggs
('hello', 'world', 21, 31)
>>> eggs[2]
21
>>> eggs[1:3]
('world', 21)
>>> len(eggs)
4
- 元組像字串一樣,是不可變的,它的值不能被修改、新增、或刪除。
>>> eggs = (1,3,5,10,23)
>>> eggs
(1, 3, 5, 10, 23)
>>> eggs[0] = 20
Traceback (most recent call last):
File "<pyshell#233>", line 1, in <module>
eggs[0] = 20
TypeError: 'tuple' object does not support item assignment
如果元組中只有一個值,那麼需要在該值後面加入一個 “,” 。 否則python 就會認為是一個普通括號內輸入了一個值。 逗號告訴python 這是一個元組。
>>> type(('hello',))
<class 'tuple'>
>>> type(('hello'))
<class 'str'>
使用元組因為他是不可變的,內容不會變化,Python可以實現一些優化,讓使用元組的程式碼比使用列表的程式碼更快。
用list() 和 tuple()來轉換型別
list() 返回傳給它們的值的列表。
tuple() 返回傳遞給他們的值的元組。
>>> spam = ('hello','world',1,3)
>>> spam
('hello', 'world', 1, 3)
>>> list(spam)
['hello', 'world', 1, 3]
>>> tuple(['cat','dog'])
('cat', 'dog')
>>> list('hello')
['h', 'e', 'l', 'l', 'o']
如果需要一個元組的可變版本,那麼可以將元組轉換為列表。
引用
這裡的類似於java 中的,值傳遞和引用傳遞。
對於int、float等 變數儲存的是值, 而對於列表、元組 變數儲存的是引用。
對比下面兩個例子:
值傳遞:
>>> spam = 42
>>> cheese = spam
>>> cheese
42
>>> spam = 100
>>> spam
100
>>> cheese
42
引用傳遞:
>>> spam = ['hello','world','a','b']
>>> cheese = spam
>>> cheese
['hello', 'world', 'a', 'b']
>>> cheese[1] = 'def'
>>> cheese
['hello', 'def', 'a', 'b']
>>> spam
['hello', 'def', 'a', 'b']
傳遞引用
對於函式,引用引數,當函式被呼叫時,引數的值被複制給變元(形參)。對於列表,變元獲取到的是 列表引用的拷貝。
def process(eggsData):
eggsData[0] = '123'
eggs = ['a','b','c']
process(eggs)
print(eggs)
copy模組的 copy()和 deepcopy()函式
這裡類似Java中的 淺拷貝和深拷貝。
在使用函式前,首先需要 import copy .
copy()用來複制列表或字典這樣的可變值,而不知是引用。
deepcopy() 用來複制 列表中包含列表的情況。
import copy
spam = ['a','b','c']
cheese = copy.copy(spam)
cheese[1] = 42
print(spam)
print(cheese)
輸出結果:
['a', 'b', 'c']
['a', 42, 'c']
小結
- 列表可以儲存很多資料,並且只有一個變數
- 列表時可變的,元組和字串雖然某些方面像列表,但是是不可變的。
- 包含一個元組的或者字串的變數,可以被一個新的元組或字串複寫,直接把引用修改了。 和 append,remove方法的修改,不是一回事。
- 變數不直接儲存列表的值,儲存的是對列表的引用。
- 需要對一個變數中的列表修改,同時不修改原來的列表,可以使用 copy 和 deepcopy()