python基礎(chǔ)教程筆記(chapt.2&4) 數(shù)據(jù)結(jié)構(gòu)

數(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]]
  1. 索引(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
  1. 分片(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

  2. 加(adding)

  • 相同類型的序列,直接用+相加,變成一個序列
  • 不相同類型的序列,不能相加
  1. 乘(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

  1. 檢查某個元素是否屬于序列成員(查看權(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'
  1. 計(jì)算序列長度
    len(序列x)
  2. 找到最大元素
    max(序列x)
  3. 最小元素
    min(序列x)
  4. 迭代
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ù))

  1. append(元素) 在列表最末尾加上新元素,改變原list
  2. count(元素) 統(tǒng)計(jì)某個元素出現(xiàn)次數(shù),返回次數(shù)
  3. extend(元素) 在列表末尾追加另一個序列的多個值,改變原list
  4. index(元素), 找到該元素的索引, 返回索引
  5. insert(要插入位置的索引, 要插入的元素):插入元素到目標(biāo)索引,改變原list
  6. 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ì)列
  7. 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])

方法:

  1. clear(為空): 清空字典,和sort一樣,改變原字典,不返回值(或者說返回值為None)
  2. 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'}
  1. fromkeys(鍵列表,自定義默認(rèn)值): 建立以提供的鍵列表為基礎(chǔ)自定義默認(rèn)值(不填就是None)的字典,返回創(chuàng)建字典。{}.fromkeys(['names'.'age']);dict.fromkeys(['names'.'age'],'(unknown)')
  2. 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)
  1. has_key(鍵):檢查是否有這個鍵,返回布爾值。3.0版沒有這個函數(shù)?。?!和 k in d一樣的功能。
  2. items(為空)和iteritmes(為空):前者將字典以[(鍵,值),(鍵,值),(鍵,值)]的列表形式返回,無特殊順序。后者作用一樣,不過返回的是迭代器對象。
  3. keys和iterkeys:和上面一樣,前后者區(qū)別也一樣,不過是只顯示鍵。
    8.vales()和itervalues():和上面一樣,前后者區(qū)別也一樣,不過是只顯示值。
  4. 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。
  5. update(更新內(nèi)容字典): 用更新內(nèi)容字典更新對象字典,新建會添加,相同建會覆蓋對象字典原有值。

集合(set)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容