Python學習筆記-第二章 列表和元組

去了趟廈門,剛回來就開始學習了,真是佩服自己呢。廈門這地兒,去一次就夠了,裝13聖地,跟我的風格不是很搭,我主要是去吃的,各種海鮮都炒雞便宜,衝着這個,大概還會再去一趟吧,每家都有團購,真是大衆點評的根據地。好了,言歸正傳,開始學習吧。

第二章 列表和元組

本章開始講數據結構。數據結構是通過某種方式(如編號)組織在一起的數據元素的集合。可以是數字或者字符,也可能是其它數據結構。

Python中最基本的數據結構是序列(sequence)。序列中每個元素都被分配一個序號(即元素的位置,也稱爲索引),第一個是0,第二個是1,依此類推。

2.1 序列概覽

Python有6種內建的序列,本章重點討論最常用的兩種類型:列表和元組。其它序列類型有:字符串,Unicode字符串,buffer對象和xrange對象。

列表跟元組的區別:列表可以修改,元組不能。大多數情況下,列表可以替代元組(也有例外,當元組作爲字典的鍵,因爲鍵不可修改,所以不能用列表)

需要操作一組數據時,序列很好用。可以用序列表示數據庫中一個人的信息,第1個元素是姓名,第2個是年齡,根據上述內容編寫一個列表:

edward=['Edward Gumby',42]
john=['John Smith',50]
database=[edward,john] #結果出現 [['Edward Gumby', 42], ['John Smith', 50]]
Python中還有一個名爲容器(container)的數據結構,它是包含其它對象的任意對象,序列和映射是兩類主要的容器。容器集合(set)既不是序列也是不是映射。

2.2 通用序列操作

 2.2.1 索引

序列中的都有編號,從0開始遞增,可以通過編號來訪問這些元素

greeting='hello'
greeting[0] #結果顯示第一個元素,'h'
使用負數索引時,是從右邊開始計數,即最後一個。
greeting[-1] #結果爲'o',即最後一個元素。
不能超過元素個數範圍

greeting[5] #會報錯,因爲這個位置不存在元素
<pre name="code" class="python">greeting[-6] 同上

如果是調用返回同一個序列,可以直接對返回結果進行索引操作。

fourth=input('year:')[3] #只對輸入年份的末位數字感興趣
year:2005
fourth #結果顯示爲'5'


#根據給定的年月日以數字形式打印出日期
months=[
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
    'August',
    'September',
    'October',
    'November',
    'December'
    ]
#以1~30的數字作爲結尾的列表
endings=['st','nd','rd']+17*['th']\
         +['st','nd','rd']+7*['th']\
         +['st']
year=input('year:')
month=input('Month(1-12):')
day=input('DAY(1-31):')
month_number=int(month)
day_number=int(day)
#記得要將月份和天數減1,以獲得正確的索引
month_name=months[month_number-1]
ordinal=day+endings[day_number-1]
print(month_name+' '+ordinal+','+year)
      
2.2.2 分片

分片是訪問一定範圍內的元素,通過冒號相隔的兩個索引來實現。

tag='<a href="http://www.python.org">python web site</a>'
tag[9:30] #結果爲'http://www.python.org',顯示編號9到編號30的元素。
tag[32:-4] #運行結果'python web site',顯示編號32起至倒數第4個元素。 

分片的操作需要提供兩個索引作爲邊界,第1個索引的元素是包含在分片內的,第2個不包含。

1.優雅的捷徑

如果需要訪問最後三個,可以有如下操作

numbers=[1,2,3,4,5,6,7,8,9,10]
numbers[3:6] #運行結果[4, 5, 6]
numbers[-3:-1] #這個結果不是想要的,最後一位元素無法顯示,只顯示[8, 9]
numbers[-3:0] #顯示[],如果在分片中最左邊的索引比右邊的晚出現在序列中,結果就是空的序列。
numbers[-3:] #最後一個索引空置就可以出現正確結果了,[8,9,10] 
numbers[:3] #同樣適用於序列開始的元素,結果顯示[1,2,3] 
numbers[:] #複製整個序列。

#對http://www.something.com形式的URL進行分割
url=input('please enter the URL:')
domain=url[11:-4]
print("domain name:"+domain)   #提取域名

2.更大的步長。

步長(step lenth)參數通常是隱匿設置的,在普通的分片中,步長是1,分片操作就是按照這個步長逐個遍歷序列的元素,然後返回開始和結束點之間的所有元素。

numbers=[1,2,3,4,5,6,7,8,9,10]  #中間運行了其它程序,所以要重新定義一遍numbers
numbers[0:10:1]  #運行結果爲[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],定義了步長爲1
numbers[0:10:2] #運行結果爲[1,3,5,7,9]
numbers[3:6:3] #運行結果爲[4]
numbers[::4] #運行結果爲[1,5,9]
numbers[8:3:-1] #步長可以是負數,即從右向左提取元素,運行結果[9,8,7,6,5]
注意:

  • 步長不能爲0
  • 開始點的元素(最左邊的)包括在結果之中,結束點的不在
  • 當使用負數爲步長時,必須讓開始點(開始索引)大於結束點。

2.2.3 序列相加

通過加號可以進行序列的連接操作,兩種同一類型的序列才能進行連接。

[1,2,3]+[4,5,6,7] #運行結果[1, 2, 3, 4, 5, 6, 7],跟兩個序列元素數量無關
'hello,'+'world!'
"hello,"+'world!'
'hello,world!' #這三個都可以正確顯示'hello,world!'
"hello,"+"1,2,3" #顯示'hello,1,2,3',這裏的1,2,3是字符
[1,2,3]+'hello'#報錯,不是同一類型

2.2.4 乘法

用數字X乘以一個序列會生成新的序列,在新序列中,原來的數列會重複X次。

'python'*5   #運行結果'pythonpythonpythonpythonpython'
[42]*5   #運行結果[42, 42, 42, 42, 42],這裏的[42]是序列而不是數字。
 '42'*5  #運行結果'4242424242',這裏的‘42’表示字符串
[1,2,3]*5   #運行結果 [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
None、空列表和初始化

空列表可以用兩個中括號表示[],如果 想要生成一個佔用10個元素的空間,卻不包含任何內容,就要用到None.

[]*5  #運行結果顯示[]
[None]*5  #運行結果[None, None, None, None, None],這裏的None首字母一定要大寫,否則報錯
[]+[] #運行結果[]
[]+[1,2,3] #運行結果[1,2,3]
[]+[None] #運行結果[None]

序列(字符串)乘法示例

#以正確的寬度在居中的“盒子”內打印一個句子
sentence=input("setence:")
screen_width=80
text_width=len(sentence)#?爲什麼
box_width=text_width+6
left_margin=(screen_width-box_width)//2
print
print(' '*left_margin+'+'+'-'*(box_width-6)+ '+')  #<span style="color:#6633FF;">修改了原來的語句才合適,版本差異?原來是-2,導致會長一截</span>
print(' '*left_margin+'|'+' '*text_width+'|')
print(' '*left_margin+'|'+sentence+'|')
print(' '*left_margin+'|'+' '*text_width+'|')
print(' '*left_margin+'+'+'-'*(box_width-6)+'+')
print
新版本里面應該有改動,導致按照原語句運行無法形成整齊的方格,原因待研究。

2.2.5 成員資格

檢查一個值是否在序列中,可以用in運算符。這個運算符是布爾運算符,檢查條件是否爲真,若爲真(布爾值),返回True,假則返回False。

permissions='rw'
'w' in permissions  #運行結果True
 's' in permissions  #運行結果Falseusers=['mlh','foo','bar']
input('enter your user name:') in users
enter your user name:mlh #運行結果 True
subject='$$$ Get rich now!!! $$$'
 '$$$' in subject #運行結果 True

示例,查看用戶輸入的用戶名和PIN碼是否存在於數據庫

#檢查用戶名和PIN碼
database=[
    ['albert','1234'],
    ['dilbert','4242'],
    ['smith','7524'],
    ['jones','9843']
    ]
username=input('user name:')
pin=input('PIN code:')
if[username,pin] in database: print ('Access granted')

2.2.6 長度、最小值和最大值

內建函數len,min和max.

Len:返回序列中所包含元素的數量。

min:返回最小的元素

max:返回最大的元素

numbers=[100,34,678]
len(numbers)  #序列中共有3個元素,所以返回值爲3
max(numbers) #返回值678
min(numbers) #返回值34
max(2,3) #也可以直接使用,3<pre name="code" class="python">min(9,3,2,5) #返回2
max[2,3] #報錯

2.3 列表:Python的苦力

2.3.1 list函數

字符串不能像列表一樣被修改,根據字符串創建列表很有用。

list('hello')  #返回值['h', 'e', 'l', 'l', 'o']
list([1,2,3]) #返回值[1, 2, 3],list函數適用於所有類型的序列

2.3.2 基本的列表操作

1.改變列表:元素賦值

x=[1,1,1]
x[1]=2
x  #返回值[1, 2, 1],x已改變

2.刪除元素(del)

names=['Alice','Beth','Cecil','Dee-Dee','Earl']
del names[2]
names  #返回值['Alice', 'Beth', 'Dee-Dee', 'Earl'],已刪除索引標記爲2的元素'Cecil'.

3.分片賦值

name=list('Perl')
name   #運行結果['P', 'e', 'r', 'l']
name[2:]=list('ar')
name #運行結果['P', 'e', 'a', 'r'],從第3個元素起變成a,r
name[2:]=list('ars')
name #運行結果['P', 'e', 'a', 'r','s'] #長度可以不相等
numbers=[1,5]
numbers[1:1]=[2,3,4] #在第二個位置插入序列
numbers    #運行結果[1, 2, 3, 4, 5]
numbers[1:4]=[]  #刪除元素
numbers #返回值[1,5]

2.3.3 列表方法

方法是一個與某些對象有緊密聯繫的函數。方法的調用形式爲:對象.方法(參數)

列表方法
append 在列表末尾追加新的對象
count 統計某個元素在列表中出現的次數
extend 在列表末尾一次性追加另一個序列中的多個值
index 從列表中找出某個值第一個匹配項的索引位置
insert 將對象插入到列表中
pop 移除列表中的一個元素(默認最後一個),並返回該元素的值
remove 移除列表中某個值的第一個匹配項
reverse 將列表中的元素反向存放
reversed 對一個序列進行反向迭代
sort 在原位置對列表進行排序
sorted 獲取已排序列表副本
高級排序 按特定方式進行排序


1.append

lst=[1,2,3] #第一個字符爲字母l,變量名第一個不能爲數字,也不能用list,一旦用了內建函數作爲變量名,它就不能被調用了
lst.append(4)
lst  #返回值[1, 2, 3, 4]

2.count

['to','be','or','not','to','be'].count('to') #'to'在列表中出現的次數,返回2
x=[[1,2],1,1,[2,1,[1,2]]]
x.count(1) #返回值爲2
x.count([1,2]) #返回值爲1

3.extend

a=[1,2,3]
b=[4,5,6]
a.extend(b)
a  #返回值[1, 2, 3, 4, 5, 6]
a=[1,2,3]
b.extend(a)
b   #返回值[4, 5, 6, 1, 2, 3]
這個用法類似於序列相加,但是序列相加不改變原變量值。如果想要改變變量a的值,需要加上一條a=a+b

也可以用分片賦值,

a=[1,2,3]
b=[4,5,6]
a[len(a):]=b
a            #返回[1, 2, 3, 4, 5, 6],分片賦值真是萬能的啊!

4.index

knights=['we','are','the','knights','who','say','ni']
knights.index('who') #返回值4
knights.index('herring')   #提示錯誤,herring不在list中

5.insert

numbers=[1,2,3,4,5,6,7]
numbers.insert(3,'four')
numbers      #返回值[1, 2, 3, 'four', 4, 5, 6, 7],'four'被插入到索引爲3的位置上
萬能的分片賦值也可以做到。

numbers=[1,2,3,4,5,6,7]
numbers[3:3]=['four']
nmbers  #可讀性不如insert。

6.pop

x=[1,2,3]
x.pop()  #這裏會先返回值3,默認移除最後一個元素
x  #返回值[1, 2],x序列已變。
x.pop(0) #返回值1
x  #返回值[2]。pop是唯一一個既能修改列表又返回元素值(除了None)的列表方法

用pop方法可以實現一種常見的數據結構——棧。棧的原則是後進先出(LIFO).棧的操作有兩個,入棧(push)和出棧(pop),python中沒有入棧,可以通過append方法來代替。

x=[1,2,3]
x.append(x.pop())
x   #返回值[1, 2, 3],入棧的是剛出棧的值,結果還是原來的棧。

7.remove

x=['to','be','or','not','to','be']
x.remove('be') #沒有返回值,直接修改
x  #返回值['to', 'or', 'not', 'to', 'be'],第一個匹配的'be'已經被移除。
x.remove('bee')  #報錯,'bee'不存在。

8.reverse

x=[1,2,3]
x.reverse() 
x    #返回值[3, 2, 1]

如果需要對一個序列進行反向迭代,可以會用reversed函數

x=[1,2,3]
reversed(x)  #返回值是<list_reverseiterator object at 0x00000000035D7B70>,reversed函數返回的是一個迭代器對象
list(reversed(x)) #返回值[3, 2, 1],用list函數把它轉換成列表。

9.sort

x=[4,6,2,1,7,9]
x.sort() 
x    #返回值[1, 2, 4, 6, 7, 9],按順序排列
sort是沒有返回值的,因此下面的做法是錯誤的

x=[4,6,2,1,7,9]
y=x.sort()
print(y)   #返回值None,sort沒有返回值
x    #返回值[1, 2, 4, 6, 7, 9],被排序了
正確的做法如下

x=[4,6,2,1,7,9]
y=x[:] #先對y賦值,把x列表複製進y
y.sort()  
x  #返回值[4, 6, 2, 1, 7, 9]
y   #返回值[1, 2, 4, 6, 7, 9]
複製整個列表不能用簡單的賦值,

x=[4,6,2,1,7,9]
y=x
y.sort()
x  #返回值[1, 2, 4, 6, 7, 9]
y    #返回值[1, 2, 4, 6, 7, 9]
獲取已排序列表副本還可以用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]
sorted的返回值總是返回一個列表

sorted('python')   #返回值['h', 'n', 'o', 'p', 't', 'y']

10.高級排序

python 3.4中cmp函數已被刪除。

其它的高級排序方法

x=['aardvark','abalone','acme','add','aerate']
x.sort(key=len)  #按長度進行排序,如果有長度一樣的單詞,會保持原來位置
x        #返回值['add', 'acme', 'aerate', 'abalone', 'aardvark']

x=[4,6,2,1,7,9]
x.sort(reverse=True)  #這裏的True首字母必須大寫,否則報錯
x   #返回值[9, 7, 6, 4, 2, 1]

2.4 元組:不可變序列

元組也是一種序列,不能修改(字符串也是這樣)。用逗號分隔一些值就自動創造了元組,元組(大部分時候)通過圓括號括起來的,空元組就是()

1,2,3   #返回值(1, 2, 3)
a,b,c   #報錯字符必須要用引號
'a','b','c'  #返回值('a', 'b', 'c') 
42, #返回一個值的元組(42,)
42  #返回42,這不是一個元組
(42) #返回42,也不是元組,創建元組的關鍵在逗號,跟括號無關
3*(40+2)  #返回值126,就是數值運算
3*(40+2,)  #返回值(42, 42, 42),先進行運算後變成元組
3*(40,+2)  #返回值(40, 2, 40, 2, 40, 2)

2.4.1 tuple函數

跟list函數基本一樣:以一個序列作爲參數並把它轉換爲元組。

tuple([1,2,3])  #返回值(1, 2, 3)
tuple('abc')   #返回值('a', 'b', 'c')
tuple((1,2,3))  #返回值(1, 2, 3),本身就是元組,返回自身

2.4.2 基本元組操作

元組只有創建元組和訪問元組。

x=1,2,3
x[1]  #返回值2,
x[0:2]   #返回值(1, 2),元組的分片還是元組 

2.4.3 那麼,意義何在

大部分時候,列表可以滿足對序列的所有需求。由於以下兩個原因,元組無可替代

  1. 元組可以在映射(和集合的成員)中當作鍵使用,列表不行
  2. 元組作爲很多內建函數和方法的返回值存在。














發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章