數(shù)據(jù)結(jié)構(gòu)
通過某種方式(例如對元素進(jìn)行編號)組織在一起的數(shù)據(jù)元素的集合,這些數(shù)據(jù)元素可以是數(shù)字或者字符,甚至可以是其他數(shù)據(jù)結(jié)構(gòu)
容器(container)
包含其他對象的任意對象。序列(例如列表和元組)和映射(字典)是兩類主要容器
序列(sequence)
索引: 每個元素被分配的號,即元素的位置。每個元素都有自己的編號
>>>edward=['Edward Gumby', 42
>>>john=['John Smith', 50]
>>>database=[edward, john]
>>>database
[['Edward Gumby', 42],['John Smith', 50]]
-
索引(indexing)
正數(shù)從0開始, 倒數(shù)-1開始,字符串可以直接索引
>>>greeting='Hello'
>>>greeting[0]
'H'
>>>greeting[-1]
'o'
>>>'Hello'[1]
'e'
取用戶輸入的年份第4位
>>>fourth=raw_input('Year: ')[3]
Year: 2005
>>>fourth
'5'
練習(xí): 要求輸入年,月,日,打印相應(yīng)日期連續(xù)格式,月份按單詞。
#-*- coding:utf-8 –*-
# 根據(jù)給定的年月日打印相應(yīng)的日期的月份名稱
months=['January', 'February', 'March','April', 'June', 'July','August', 'September', 'October', 'November', 'December']
# 以1-31的數(shù)字作為結(jié)尾的列表
endings=['st','nd','rd']+ 17*['th']+['st','nd','rd']+7*['th']+['st']
year=raw_input('Year: ')
month=raw_input('Month (1-12): ')
day=raw_input('day(1-31) ')
month_number=int(month)
day_number=int(day)
#月份,日期減1,獲得正確索引
month_name=months[month_number-1]
original=day+endings[day_number-1]
print month_name+' '+ original+' '+year
分片(sliceing)[起:終:步長]
分片操作需要提供兩個索引作為便捷,第一個元素包含在分片內(nèi),第二個不包含。
10個數(shù),1,2,3,4,5,6,7,8,9,10
取全部:[:] 1,2,3,4,5,6,7,8,9,10
取索引至5(不包括5):[:5] 1,2,3,4,5
取索引6起(包括6)后所有:[5:] 6,7,8,9,10
取索引6起(包括6)后所有(已知索引最后位才可用,索引為10的數(shù)不存在,不過也不用取,所以不影響):[5:10] 6,7,8,9,10
取索引1起至索引3(不包括3):[1:3] 1,2,3
取倒數(shù)第3個至第一個[-3, -1]:
步長不能為0,可以為負(fù)數(shù)。負(fù)數(shù)時表示從右往左提取,索引也反過來寫
索引為8的至索引為3的[8:3:-1] : 9,7,6,5加(adding)
- 相同類型的序列,直接用
+相加,變成一個序列 - 不相同類型的序列,不能相加
- 乘(multiplying)
用數(shù)字x乘一個序列,序列會生成一個將原來序列重復(fù)N次的新序列
常用初始化列表:
>>>sequence=[None]*10
練習(xí): 其中書是box_width-2,我跑了發(fā)現(xiàn)不對,改成4.
#-*- coding:utf8 -*-
#以正確的寬度在居中的盒子內(nèi)打印一句話
#注意,正數(shù)除法運(yùn)算符//只能用在python 2.2以后版本,之前版本,只能用普通除法
sentence=raw_input("Sentence: ")
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-4)+ '+'
print ' '* left_margin+'| '+' '* text_width + ' |'
print ' '* left_margin+'| '+ sentence + ' |'
print ' '* left_margin+'| '+' '* text_width + ' |'
print ' '* left_margin+'+' +'-'* (box_width-4)+ '+'
print
- 檢查某個元素是否屬于序列成員(查看權(quán)限,提供的用戶名是否存在等安全策略, 垃圾郵箱過濾)
'信息' in 序列名
得到的結(jié)果是布爾值
>>>raw_input('Enter your user name: ') in users
Enter your user name:m1h
True
練習(xí): 檢查用戶名和密碼是否匹配
#-*- coding:utf8 -*-
#檢查用戶名和密碼
database=[['albert', '1234'], ['dilbert','4242'],['smith','7524'],['jones','9843']]
username=raw_input('User name: ')
pin=raw_input('Pin code: ')
if[username, pin] in database: print 'Access granted'
- 計(jì)算序列長度
len(序列x) - 找到最大元素
max(序列x) - 最小元素
min(序列x) - 迭代
1. 列表list
可修改(mutable).
創(chuàng)建: x=[列表內(nèi)容] 創(chuàng)建字符串列表可以直接 list('字符串') 會生成一個一個字符單個作為一個元素的列表。
' '.join(somelist)
修改: x[要修改的元素索引位置]=修改目標(biāo)值
刪除: del x[要刪除的索引位置],會將列表變小。
分片賦值: 通過分片賦值可以達(dá)到批量修改(不局限列表長度),批量插入新元素(x[1:1]=[插入內(nèi)容]), 刪除元素(x[2:4]=[])
--------列表的方法:----
對象.方法(參數(shù))
- append(元素) 在列表最末尾加上新元素,改變原list
- count(元素) 統(tǒng)計(jì)某個元素出現(xiàn)次數(shù),返回次數(shù)
- extend(元素) 在列表末尾追加另一個序列的多個值,改變原list
- index(元素), 找到該元素的索引, 返回索引
- insert(要插入位置的索引, 要插入的元素):插入元素到目標(biāo)索引,改變原list
- pop(為空是移除最后一個,或者填要移除的索引):移除list中最后一個或者索引對應(yīng)元素,返回該被移除的元素,改變原list
數(shù)據(jù)結(jié)構(gòu):棧 (入棧,出棧)
用append()+pop()實(shí)現(xiàn)LIFO后進(jìn)先出的隊(duì)列
用insert(0,...)+pop()或者pop(0)+append()或者collection.deque實(shí)現(xiàn)FIFO先進(jìn)先出隊(duì)列 - remove(元素):移除第一個匹配項(xiàng),無返回值,改變原list
8.reverse(空): 將列表中的元素反過來存放,改變原list,返回的是一個迭代器對應(yīng)
9.sort(cmp, key, reverse):將列表排序。改變原list,返回值為None。key是依照排序的對象,比如按照元素長度排序,就key=len,reverse為布爾值,是否反響排序,填True 或者False.cmp同compare
sorted(x):將列表排序,不改變原list,輸出排序后的list,故而如需保存需要賦值。該函數(shù)可用于任何可迭代對象
10.compare(x,y):高級排序,當(dāng)x<y時,返回負(fù)數(shù),x>y時,返回正數(shù),x=y則返回0
x.sort().reverse() 不可行,因?yàn)閟ort()返回值為None
sorted(x).reverse() 可行

2. 元組tuple
不可修改
創(chuàng)建:(x,); x,; tuple()
映射
映射可以使用任何不可變對象標(biāo)識元素,常見類型是字符串和元組,python唯一的內(nèi)建映射就是字典。
鍵: 每個元素都有自己的名字,唯一
1.字典
適用于: 象征游戲棋盤的狀態(tài),每個鍵都是由坐標(biāo)值組成的元組;存儲文件修改次數(shù),用文件名作為鍵;數(shù)字電話/地址簿
創(chuàng)建:{}; dict([(鍵),(值)]); dict(鍵名=鍵, 值名=值)
查看鍵-值數(shù)量:len(字典)
查值: 字典名[鍵]
關(guān)聯(lián)(賦值): 字典[鍵]=值
刪除某鍵及對應(yīng)值: del 字典[鍵]
檢查是否存在: 鍵 in 字典
練習(xí) 書里少了一行關(guān)于request定義。
#-*- coding=utf8 -*-
#簡單數(shù)據(jù)庫
#使用人名作為鍵的字典,每個人用另一個字典來表示,其鍵'phone'和'addr'分別表示他們的電話號碼和地址
people={'Alice':{'phone':'2341','addr':'Foo drive 23'}, 'Beth':{'phone':'9102','addr':'Bar street 42'},
'Ceil':{'phone':'3158','addr':'Baz avenue 90'}}
#針對電話號碼和地址是用的描述性標(biāo)簽,會在打印輸出的時候用到
label={'phone':'phone number','addr':"address"}
name=raw_input('Name: ')
request=raw_input('Phone number(p) or address (a)?')
#查找電話號碼還是地址? 使用正確的鍵
#使用正確的鍵
if request == 'p':key='phone'
if request == 'a':key="addr"
#如果姓名是字典中的有效鍵才打印
if name in people: print "%s's %s is %s" % (name,label[key],people[name][key])
方法:
- clear(為空): 清空字典,和sort一樣,改變原字典,不返回值(或者說返回值為None)
- copy(為空):返回一個相同鍵-值的新字典,屬于淺復(fù)制,大概就是在副本中替換值(比如用賦值),原始字典不受影響,但是如果在副本當(dāng)中進(jìn)行了修改(比如刪除了某個值),原始字典里的也會進(jìn)行同樣的操作。
深復(fù)制: copy.deepcopy
>>>from copy import deepcopy
>>>d={}
>>>d['names']=['Alfred','Bertrand']
>>>c=d.copy()
>>>dc=deepcopy(d)
>>>d['names].append('Clive')
>>>c
{'names':['Alfred','Bertrand','Clive;]}
>>>d
{'names':['Alfred','Bertrand'}
- fromkeys(鍵列表,自定義默認(rèn)值): 建立以提供的鍵列表為基礎(chǔ)自定義默認(rèn)值(不填就是None)的字典,返回創(chuàng)建字典。
{}.fromkeys(['names'.'age']);dict.fromkeys(['names'.'age'],'(unknown)') - get(鍵,自定義鍵不存在時返回啥):訪問字典項(xiàng), 鍵不存在返回自定義的值(不填返回None),存在返回值。
練習(xí) 基于上面簡單數(shù)據(jù)庫加入get的應(yīng)用,和格式化一起用,真的很方便,少打一萬行字,深切感受到格式化的強(qiáng)大。這人怎么就這么聰明呢。
#-*- coding=utf8 -*-
#使用get()的簡單數(shù)據(jù)庫
#使用人名作為鍵的字典,每個人用另一個字典來表示,其鍵'phone'和'addr'分別表示他們的電話號碼和地址
people={'Alice':{'phone':'2341','addr':'Foo drive 23'}, 'Beth':{'phone':'9102','addr':'Bar street 42'},
'Ceil':{'phone':'3158','addr':'Baz avenue 90'}}
#針對電話號碼和地址是用的描述性標(biāo)簽,會在打印輸出的時候用到
labels={'phone':'phone number','addr':"address"}
name=raw_input('Name: ')
#查找電話號碼還是地址?
request=raw_input('Phone number(p) or address (a)?')
#使用正確的鍵
key=request #如果請求既不是p也不是a
if request == 'p':key='phone'
if request == 'a':key="addr"
#使用get()提供默認(rèn)值
label=labels.get(key,key)
person=people.get(name,{})
result=person.get(key,'not available')
#如果姓名是字典中的有效鍵才打印
print "%s's %s is %s" % (name,label,result)
- has_key(鍵):檢查是否有這個鍵,返回布爾值。3.0版沒有這個函數(shù)?。?!和 k in d一樣的功能。
- items(為空)和iteritmes(為空):前者將字典以[(鍵,值),(鍵,值),(鍵,值)]的列表形式返回,無特殊順序。后者作用一樣,不過返回的是迭代器對象。
- keys和iterkeys:和上面一樣,前后者區(qū)別也一樣,不過是只顯示鍵。
8.vales()和itervalues():和上面一樣,前后者區(qū)別也一樣,不過是只顯示值。 - pop(鍵): 刪除對應(yīng)鍵-值,并且返回該鍵-值。
10.popitem(為空): 隨機(jī)刪除字典中的一項(xiàng),在想實(shí)現(xiàn)不用獲取鍵列表的前提下,一個個地移除并處理項(xiàng)時很實(shí)用。
11.setdefault(鍵盤,自定義默認(rèn)值):在鍵存在時,返回鍵對應(yīng)的目前值,鍵不存在時,增加鍵,并設(shè)定為默認(rèn)值,默認(rèn)值不填時默認(rèn)None。 - update(更新內(nèi)容字典): 用更新內(nèi)容字典更新對象字典,新建會添加,相同建會覆蓋對象字典原有值。