1. 程式人生 > >python快速上手_第四章 列表

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()