python數據結構
學一門語言,最基礎和重要的就是數據結構了,而在python中最基本的數據結構是序列,也可以理解爲數組,但貌似比數組強大。
>>> jason=['jason',42] >>> james=['james',45] >>> database=[jason,james] >>> database [['jason', 42], ['james', 45]] >>>
索引:
>>> greeting='hello' >>> greeting[0] 'h' >>> greeting[-1] ==>反着的時候從-1而不是0開始開始 'o' >>> digital=raw_input ("year:")[3] year:2013 >>> digital '3'
索引示例:
>>> months=['January','February','March','April',\ 'May','June','July','August','September','October'\ 'November','December'] #根據指定的年月日以數字形式打印出日期 >>> endings=['st','nd','rd']+17*['th']+['st','nd','rd']+7*['th']+['st'] #以1-31的數字作爲結尾的列表 >>> year=raw_input ("Year:") Year:2013 >>> month=raw_input('Month(1-12):') Month(1-12):3 >>> day=raw_input('Day(1-31):') Day(1-31):30 >>> month_num=int(month) >>> day_num=int(day) >>> month_name=months[month_num-1] ==>注意這裏索引要減1 >>> ordinal=day+endings[day_num-1] >>> print month_name +' '+ordinal + ', '+ year March 30th, 2013 >>>
分片:
使用索引能訪問單個元素,使用分片能訪問一定範圍的元素,分片通過冒號相隔的兩個索引來實現。
>>> tag='<a href="http://www.python.org">Python web site</a>' >>> tag[9:30] 'http://www.python.org' >>> tag[32:-4] 'Python web site'>>>
>>> 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[:] #默認全部 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
很顯然,分片操作的實現需要提供兩個索引作爲邊界,第一個索引的元素包含在分片內,而第二個不包含在分片內。
分片步長:默認步長沒有寫,是1,分片格式:上邊界:下邊界:步長
>>> numbers[0:10:1] #默認步長是1 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> numbers[0:10:2] #步長設爲2 [1, 3, 5, 7, 9] >>> numbers[3:6:3] #步長設爲3 [4] >>> numbers[::4] [1, 5, 9] >>> numbers[8:3:-1] #步長不能爲0,因爲不會向下執行,可以爲負數,向前執行 [9, 8, 7, 6, 5] >>> numbers[10:0:-2] #當步長爲負數時,開始索引必須大於結束索引 [10, 8, 6, 4, 2] >>> numbers[0:10:-2] [] >>> numbers[::-2] [10, 8, 6, 4, 2] >>> numbers [5::-2] [6, 4, 2] >>> numbers[:5:-2] [10, 8] >>>
序列相加:
>>> [1,2,3]+[4,5,6] [1, 2, 3, 4, 5, 6] >>> [1,2,3]+'world' #列表和字符串都是序列,但是不能連在一起,兩種同類型的序列才能進行連接操作 Traceback (most recent call last): File "<pyshell#141>", line 1, in <module> [1,2,3]+'world' TypeError: can only concatenate list (not "str") to list >>>
序列乘法:
>>> 'python'*5 'pythonpythonpythonpythonpython' >>> [25]*10 [25, 25, 25, 25, 25, 25, 25, 25, 25, 25]
空列表可以簡單的通過[ ]表示,但若想要創建一個佔用十個元素空間,卻不包括任何有用的有用的內容列表。這時需要使用None,None是Python的內建值,初始化一個長度爲10的列表如下:
>>> sequence=[None]*10 >>> sequence [None, None, None, None, None, None, None, None, None, None]
序列乘法示例:(存在腳本中運行)
sentence=raw_input ("Sentence:") screen_width=60 text_width=len(sentence) box_width=text_width+6 left_margin=(screen_width-box_width)//2 print print ' ' * left_margin + '+' + '-' * (box_width-2) + '+' print ' ' * left_margin + '| ' + ' ' * text_width +' |' print ' ' * left_margin + '| ' + sentence +' |' print ' ' * left_margin + '| ' + ' ' * text_width +' |' print ' ' * left_margin + '+' + '-' * (box_width-2) + '+' print raw_input()
結果如下:
in運算符:檢查一個值是否在序列中
>>> permission='rwx' #有木有覺得這個像判斷Linux中某個文件的執行權限,確實可以這麼判斷 >>> 'w' in permission True >>> 'xx' in permission False >>> users=['jason','james','jzhou'] >>> raw_input ("enter your name:") in users enter your name:jzhou True
序列成員資格示例:
database=[['jason','42'],['james','45'],['jzhou','22']] username=raw_input("Username:") age=raw_input("Age:") if [username,age] in database: print "OK,right" raw_input()
內建函數len、min、max
>>> numbers [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> len(numbers) 10 >>> max(numbers) 10 >>> min(numbers) 1 >>>
列表:
列表不同於元組和字符串,列表是可變的,而且列表有許多專門的方法。字符串不能像列表一樣被修改,但是列表中的list函數可以實現修改。列表的常用用法:
>>> list('hello') ['h', 'e', 'l', 'l', 'o'] >>> x=[1,1,1] >>> x[1]=2 #可以改變列表爲元素賦值 >>> x[2]=3 >>> x [1, 2, 3] >>> names=['james','jason','jzhou','liwear'] #可以刪除列表中的元素 >>> del names[3] >>> names ['james', 'jason', 'jzhou'] >>> name=list('jzhou') >>> name ['j', 'z', 'h', 'o', 'u'] >>> name[2:]=list('1314') #可以分片賦值 >>> name ['j', 'z', '1', '3', '1', '4']
>>> numbers=[1,5] #分片賦值可以在不需要替換任何元素的情況下插入新元素 >>> numbers[1:1]=[2,3,4] >>> numbers [1, 2, 3, 4, 5] >>> numbers[1:4]=[] #也可以變相的刪除元素 >>> numbers [1, 5]
列表的方法主要有append, count,extend,index,insert,pop,remove,reverse,sort,簡單用法如下:
>>> list=[1,2,3]
>>> list .append(4) # append用於在列表末尾追加新對象
>>> list
[1, 2, 3, 4]>>> ['to','be','or','to'].count('to') #count用於統計某個元素在列表中出現的次數 2 >>> x=[[1,2],1,1,[2,1,[1,2]]] >>> x.count(1) 2 >>> x.count([1,2]) 1 >>> a=[1,2,3] >>> b=[4,5,6] >>> a.extend(b) #extend在列表的末尾一次性追加另一個序列的多個值,擴展原有列表 >>> a [1, 2, 3, 4, 5, 6] #注意這個操作與連接操作不同,extend修改了被擴展的序列即a,而連接只是臨時顯示並沒有變 >>> a=[1,2,3] >>> b=[4,5,6] >>> a[len(a):]=b #也可以通過分片賦值來擴展,但是可讀性不強 >>> a [1, 2, 3, 4, 5, 6] >>> sentence=['we','are','good','student'] >>> sentence.index ('are') #index用於從列表中找出某個值第一個匹配項的索引位置 1 >>> numbers=[1,2,3,4,5,6,7] >>> numbers.insert(3,'four') #insert用於將對象插入列表中,和數據結構中的鏈表操作非常相似 >>> numbers [1, 2, 3, 'four', 4, 5, 6, 7] >>> numbers=[1,2,3,4,5,6,7] >>> numbers[3:3]=['four'] #也可以使用分片賦值的方法實現,但是可讀性不強 >>> numbers [1, 2, 3, 'four', 4, 5, 6, 7] >>> x=[1,2,3] >>> x.pop() #出棧操作,和數據結構中的棧操作一樣,即移除列表中的最後一個,並且返回該元素的值 3 >>> x [1, 2] >>> x.pop() 2 >>> x=[1,2,3] >>> x.append(x.pop()) #這個操作和數據結構中的push、pop是一樣的,追加剛剛出棧的值,很有趣,最後得到的還是是原來的值 >>> x [1, 2, 3] >>> x=['to','be','or','not','to','be'] >>> x.remove ('be') #remove用於移除列表中某個值的第一個匹配項 >>> x #值得注意的是remove方法是沒有返回值的原位置改變方法,注意和pop的區別 ['to', 'or', 'not', 'to', 'be'] >>> x=[1,2,3] >>> x.reverse () #將列表中的元素反向存放,注意這種方法改變了列表但沒有返回值 >>> x [3, 2, 1] >>> x=[4,5,6,7,1,2,3] >>> x.sort() #sort用於在原位置對列表進行排序,也改變了序列的值,但是沒有返回值 >>> x [1, 2, 3, 4, 5, 6, 7] >>>
注意以上方法除了count和index,都是會使列表的內容的產生變化。
介於sort方法修改列表但是沒有返回值的情況有待細說一下:
>>> x=[4,6,2,1,7,9] >>> y=x.sort() #因爲x.sort()不反回值,所以y並沒有賦到值 >>> print y None >>>
看下正確的做法吧,其實也就是將步驟拆開而已:(sort函數不反回值的特點決定了不能在它的後面繼續後續操作,比如x.sort().reverse(),但是serted(x).reverse()是正確的)
>>> x=[4,6,2,1,7,9] >>> y=x[:] #先將x複製給y >>> y.sort() #將y排序 >>> x [4, 6, 2, 1, 7, 9] >>> y [1, 2, 4, 6, 7, 9] >>> x=y>>> 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) >>> x [4, 6, 2, 1, 7, 9] >>> y [1, 2, 4, 6, 7, 9]
sorted函數可以用於任何序列,卻總是返回一個列表:
>>> sorted("Python") #默認按ASCII碼排序 ['P', 'h', 'n', 'o', 't', 'y']
如果想把一些元素按相反的順序排出,可以先用sort或者sorted函數,在調用reverse函數。嵌套使用的功能很強大。
關於高級排序:元素能按照特定的方式進行排序,可以使用compare(x,y)自定義比較函數,compare(x,y)函數會在x<y時返回負值,x>y時返回正值,x=y時返回0。定義好該函數之後,就可以提供給sort方法作爲參數了。
>>> cmp(42,23) 1 >>> cmp(99,100) -1 >>> cmp(1,1) 0 >>> numbers=[5,2,6,7] >>> numbers.sort(cmp) #這個機制之後會介紹 >>> numbers [2, 5, 6, 7]
元組——不可變序列
元組和列表一樣,也是一種序列,唯一的不同是元組不能修改,字符串也是如此;創建元素很簡單,用逗號分隔一些值,就自動創建了元組:
>>> 1,2,3 (1, 2, 3) >>> (1,2,3) (1, 2, 3) >>> (42,) # 逗號說明它是一個元組,不然加括號(如:(42))也沒用 (42,) >>> 3*(40+2) #這個例子說明了逗號的重要性,42和(42)是完全一樣的 126 >>> 3*(40+2,) (42, 42, 42) >>>
tuple函數:
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 >>> x[0:2] #元組的分片還是元組,就像列表的分片還是列表一樣 (1, 2)
那麼元組的存在意義是什麼呢,首先元組可以在映射中當做鍵使用,而列表不行;其次,元組作爲很多內建函數和方法的返回值存在。只要不涉及到修改元組,大部分情況下和列表基本功能相同。一般來說,列表可更能滿足對序列的所有要求。
用到的函數總結:cmp(x,y)、len(seq)(返回序列長度)、list(seq)(把序列轉換成列表)、max(args)、min(args)、reverse(seq)(對序列進行反向迭代)、sorted(seq)(返回已排序的包含seq所有元素的列表)、tuple(seq)(把序列轉換成元組)