第二章 列表和元組
在Python中,最基本的數據結構為序列(包括列表、元組、字符串等)(sequence)
列表是可以修改的,而元組不可以
Python支持一種數據結構的基本概念,名為容器(container)
容器基本上就是可包含其他對象的對象
兩種主要的容器是序列(如列表和元組)和映射(如字典)
在序列中,每個元素都有編號,而在映射中,每個元素都有名稱(也叫鍵)。
有一種既不是序列也不是映射的容器,它就是集合(set)
通用的序列操作
通用的序列操作包括索引、切片、相加、相乘和成員資格檢查
1,索引
索引中,下標從0開始訪問單個元素,0時第一個元素的位置
用負數索引時,Python將從右(即從最后一個元素)開始往左數,-1是最后一個元素的位置
beyond = "I love the band"
beyond[0]#結果為:I
beyond[2]#結果為:l
beyond[-1]#結果為:d
beyond[-2]#結果為:n
"beyond"[2]#結果為:yfourth = input('Year: ')[3]
輸入結果:Year: 1999
輸出結果:'9'
2,切片:
除使用索引來訪問單個元素外,還可使用切片(slicing)來訪問特定范圍內的元素
簡而言之,左閉右開
切片索引方向只能從左向右,不能反過來操作,即左小右大,左閉右開
若要反過來操作需要指定步長即可
number = [0,1,2,3,4,5,6,7,8,9]
number[1:3]#結果為:[1,2]
number[4:5]#結果為:[4]
number[8:10]#結果為:[8,9] 索引10,該元素壓根不存在,但是沒有報錯,壓根用不到,左閉右開number[-3:-1]#結果為:[7,8]
number[-1:-3]#結果為:[]
'''
如果第一個索引指定的元素位于第二個索引指定的元素后面
(在這里,倒數第3個元素位于第1個元素后面),結果就為空序列
'''#切片結束于序列末尾,可省略第二個索引
number[-3:]#結果為:[7,8,9]
#如果切片始于序列開頭,可省略第一個索引
number[:3]#結果為:[0,1,2]
#要復制整個序列,可將兩個索引都省略
number[:]#結果為:[0,1,2,3,4,5,6,7,8,9]
設置步長的切片
通常情況不寫步長的時候,步長默認為1
number=[0,1,2,3,4,5,6,7,8,9]
number[0:5]#結果為:[0,1,2,3,4]
number[0:5:1]#結果為:[0,1,2,3,4]
#不寫第三個參數步長的話默認為1number[0:10:2]#結果為:[0,2,4,6,8] 步長為2時,將從起點和終點之間每隔一個元素提取一個元素#要從序列中每隔3個元素提取1個,只需提供步長4即可
number[::4]#結果為:[0,4,8]#當然,步長不能為0,否則無法向前移動,但可以為負數,即從右向左提取元素
number[8:3:-1]#結果為:[8,7,6,5,4]
number[3:8:-1]#結果為:[]#步長為正數時,它從起點移到終點
#步長為負數時,它從終點移到起點
number[5::-2]#結果為:[5,3,1]
number[:5:-2]#結果為:[9,7]
3,序列相加+
[1,2,3] + [3,2,1]#結果為:[1,2,3,3,2,1]
'hello,' + "beyond"#結果為:'hello,beyond'[1,2,2] + "yanyu"#結果為:報錯!!!
#一般而言,不能拼接不同類型的序列
4,乘法*
“beyond” * 5#結果為:'beyondbeyondbeyondbeyondbeyond'
[521] * 3#結果為:[521,521,521]'''
Python中None表示什么都沒有,為空
將列表長度初始化為5如下:
'''
beyond = [None] * 5
beyond#結果為:[None,None,None,None,None]
5,成員資格in
要檢查特定的值(可以是單個字符也可以是字符串)是否包含在序列中,可使用運算符in
它檢查是否滿足指定的條件,并返回相應的值,滿足時返回True,不滿足時返回False
這樣的運算符稱為布爾運算符,而前述真值稱為布爾值
beyond = "yanyu like beyond"
'y' in beyond#結果為:True
'q' in beyond#結果為:Falseusers = ['yanyu','huangjiaju','yeshirong']
input('Enter your user name:') in users
Enter your user name:yanyu
#結果為:True
長度、最小值、最大值
函數len返回序列包含的元素個數,min和max分別返回序列中最小和最大的元素
beyond = [19,5,22]
len(beyond)#結果為:3
max(beyond)#結果為:22
min(beyond)#結果為:5max(1999,2005)#結果為:2005
min(98,55)#結果為:55
列表
函數list,使用字符串來創建列表
可將任何序列(而不僅僅是字符串)作為list的參數
list("beyond")#結果為:['b', 'e', 'y', 'o', 'n', 'd']
基本的列表操作包括索引、切片、拼接和相乘,但列表的有趣之處在于它
是可以修改的
1,修改列表:給元素賦值
beyond = [1,2,3,4,5]
beyond[1] = 99
beyond#結果為:[1,99,3,4,5]
#不能給不存在的元素賦值,因此如果列表的長度為2,就不能給索引為100的元素賦值
2,刪除元素del
yanyu = ["yanyu",1999,'huangjiaju']
del yanyu[1]
yanyu#結果為:['yanyu','huangjiaju']
3,給切片賦值
yanyu = list("beyond")
yanyu#結果為:['b', 'e', 'y', 'o', 'n', 'd']yanyu[2:] = list('SQ')
yanyu#結果為:['b','e','S','Q']
yanyu[3:] = list("jiaju")
yanyu#結果為:['b', 'e', 'S', 'j', 'i', 'a', 'j', 'u']#在不替換原有元素的情況下插入新元素
yanyu[1:1] = [6,7,8]
yanyu#結果為:['b', 6, 7, 8, 'e', 'S', 'j', 'i', 'a', 'j', 'u']
yanyu[1:3] = []
yanyu#結果為:['b', 8, 'e', 'S', 'j', 'i', 'a', 'j', 'u']
'''
這很顯然與del yanyu[1:3]等效
類推,也可以對執行步長不為1的切片進行賦值
'''
4,列表方法
方法是與對象(列表、數、字符串等)聯系緊密的函數
object.method(arguments)
方法調用與函數調用很像,只是在方法名前加上了對象和句點
列表包含多個可用來查看或修改其內容的方法
1,append,將一個對象附加到列表末尾
yanyu = [1,2,4,5,6]
yanyu.append(7)
yanyu#結果為:[1,2,4,5,6,7]
2,clear,就地清空列表的內容
yanyu = [1,2,3]
yanyu.clear()
yanyu#結果為:[]
#這類似于切片賦值語句yanyu[:] = []
3,copy,復制列表(將另一個名稱關聯到列表)
a = [1,2,3]
b = a
b[1] = 4
a#結果為:[1,4,3]
#將另一個名稱關聯到列表a = [1,2,3]
b = a.copy()
b[1] = 4
a#結果為:[1, 2, 3]
#這類似于使用a[:]或list(a),它們也都復制a
4,count,計算指定的元素在列表中出現了多少次
['to', 'be', 'or', 'not', 'to', 'be'].count('to') #結果為:2 x = [[1, 2], 1, 1, [2, 1, [1, 2]]]
x.count(1) #結果為:2
x.count([1, 2]) #結果為:1
5,extend,同時將多個值附加到列表末尾,可使用一個列表來擴展另一個列表
a = [1, 2, 3]
b = [4, 5, 6]
a.extend(b)
a #結果為:[1, 2, 3, 4, 5, 6]
#很明顯a這個列表已經發生了修改
'''
extend是將b擴展到a,a會發生變化會被擴展
而常規拼接+,只是返回一個新的序列,原本的不會被修改
'''
a = [1, 2, 3]
b = [4, 5, 6]
a + b #結果為:[1, 2, 3, 4, 5, 6]
a #結果為:[1, 2, 3]
#很明顯a這個列表并沒有改變
a = a+b#結果為:[1, 2, 3, 4, 5, 6] 效果實現了 但是拼接的效率將比extend低a = [1, 2, 3]
b = [4, 5, 6]
a[len(a):] = b
a #結果為:[1, 2, 3, 4, 5, 6]
#這雖然可行,但可讀性不是很高
6,index,查找指定值第一次出現的索引
yanyu= ['We', 'are', 'the', 'knights', 'who', 'say', 'huangjiaju']
yanyu.index('who') #結果為:4 who處于索引第4處
yanyu.index('xixihaha')#結果為:報錯 其不存在
7,insert,用于將一個對象插入列表
numbers = [1, 2, 3, 5, 6, 7]
numbers.insert(3, 'four')
numbers #結果為:[1, 2, 3, 'four', 5, 6, 7]'''
與extend一樣,也可使用切片賦值來獲得與insert一樣的效果
這雖巧妙,但可讀性根本無法與使用insert媲美
'''
numbers = [1, 2, 3, 5, 6, 7]
numbers[3:3] = ['four']
numbers #結果為:[1, 2, 3, 'four', 5, 6, 7]
8,pop,從列表中刪除一個元素(末尾為最后一個元素),并返回
這一元素
pop是唯一既修改列表又返回一個非None值的列表方法
x = [1,2,3,9,8,7]
x.pop()#結果為:7
x#結果為:[1,2,3,9,8]
x.pop(2)#結果為:3
x#結果為:[1,2,9,8]
'''
使用pop可實現一種常見的數據結構——棧(stack)后進先出
push和pop是大家普遍接受的兩種棧操作(加入和取走)的名稱
Python沒有提供push,但可使用append來替代
方法pop和append的效果相反,因此將剛彈出的值壓入(或附加)后,得到的棧將與原來相同要創建先進先出(FIFO)的隊列,可使用insert(0, ...)代替append
另外,也可繼續使用append,但用pop(0)替代pop()。
'''
x = [1,4,7]
x.append(x.pop())
x#結果為:[1,4,7]
9,remove,用于刪除第一個為指定值的元素
remove是就地修改且不返回值
的方法
不同于pop的是,它修改列表,但不返回任何值
x = ['I','love',"beyond",'and',"I",'hahaha']
x.remove("I")
x#結果為:
x.remove("SQ")#結果為:報錯 原因為列表里面沒有該元素
10,reverse,按相反的順序
排列列表中的元素
修改列表,但不返回任何值(與remove和sort等方法一樣)
x = [1, 2, 3]
x.reverse()
x #結果為:[3, 2, 1]'''
如果要按相反的順序迭代序列,可使用函數reversed
這個函數不返回列表,而是返回一個迭代器,不改變原來的列表
'''
x = [1, 2, 3]
list(reversed(x)) #結果為:[3, 2, 1]
x#結果為:[1,2,3]
11,sort,用于對列表就地排序
sort方法:對原來的列表進行修改,使其元素按順序排列,且不返回任何值
!!!
sorted函數:可用于任何序列,但總是返回一個列表
x = [7,4,1,8,9,6,5,2,3]
x.sort()
x#結果為:[1,2,3,4,5,6,7,8,9]y = [9,5,1,7,8,6]
z = y.sort()
print(z)#結果為:None 其原因在于,sort不返回任何值!!!
y#結果為:[1,5,6,7,8,9] y列表排序了,但是sort不返回任何值導致z為None#先將z關聯到y的副本,再對z進行排序
y = [9,5,1,7,8,6]
z = y.copy()
z.sort()
z#結果為:[1, 5, 6, 7, 8, 9] z進行排序
y#結果為:[9, 5, 1, 7, 8, 6] y并未修改#另一種方式是使用函數sorted
x = [4, 6, 2, 1, 7, 9]
y = sorted(x)
y #結果為:[1, 2, 4, 6, 7, 9]
x #結果為:[4, 6, 2, 1, 7, 9] #如果要將元素按相反的順序排列,可先使用sort(或sorted),再調用方法reverse,也可使用參數reversesorted('Python') #結果為:['P', 'h', 'n', 'o', 't', 'y'] 大寫字母<小寫字母,相同類型字母a或A最小
12,高級排序
方法sort接受兩個可選參數(關鍵字參數):key和reverse
參數key類似于參數cmp:你將其設置為一個用于排序的函數
參數reverse:只需將其指定為一個真值(True或False),以指出是否要按相反的順序對列表進行排序
要根據長度對元素進行排序,可將參數key設置為函數len
x = ["qwert","asf",'zx',"vxcb",'sdfsd']
x.sort(key=len)
x#結果為:['zx', 'asf', 'vxcb', 'qwert', 'sdfsd']y = [4,6,8,2,1,9,7]
y.sort(reverse=True)
y#結果為:[9, 8, 7, 6, 4, 2, 1]
元組:不可修改
的序列()
元組語法很簡單,只要將一些值用逗號分隔,就能自動創建一個元組
1,2,3#結果為:(1, 2, 3) 元組
(1,2,3)#結果為:(1, 2, 3) 元組#逗號很關鍵,若只有一個數時,不加逗號就代表數,加上逗號代表元組
1999#結果為:1999 數
1999,#結果為:(1999,) 元組
(1999,)#結果為:(1999,) 元組
函數tuple的工作原理與list很像:它將一個序列作為參數,并將其轉換為元組
如果參數已經是元組,就原封不動地返回它
tuple([1, 2, 3])#結果為:(1, 2, 3)
tuple('abc')#結果為:('a', 'b', 'c')
tuple((1, 2, 3))#結果為:(1, 2, 3)
元組的創建及其元素的訪問方式與其他序列相同
x = 1, 2, 3
x#結果為:(1,2,3)
x[1]#結果為:2
x[0:2] #結果為:(1, 2)
本章節介紹的新函數
函 數 | 描 述 |
---|---|
len(seq) | 返回序列的長度 |
list(seq) | 將序列轉換為列表 |
max(args) | 返回序列或一組參數中的最大值 |
min(args) | 返回序列和一組參數中的最小值 |
reversed(seq) | 讓你能夠反向迭代序列 |
sorted(seq) | 返回一個有序列表,其中包含指定序列中的所有元素 |
tuple(seq) | 將序列轉換為元組 |