1. 程式人生 > >列表、字典、元組、檔案——Python

列表、字典、元組、檔案——Python

列表(list):

列表是Python中最具靈活性的有序集合物件型別。

與字串不同的是列表可以包含任何種類的物件,列表都是可變物件,支援在原處修改操作,可以通過指定的偏移值和分片、列表方法呼叫、刪除語句等方法來實現。

Python列表的主要屬性:

    任意物件的有序集合——列表就是收集其他物件的地方,包含的每一項都保持從左到右的順序

    通過偏移讀取——隊列表物件通過偏移進行索引

    可變長度、異構、任意巢狀——列表可以實時的增長、縮短,可以包含任何型別的物件,支援任意巢狀

    屬於可變序列分類——支援在原處修改

    物件引用陣列——在Python直譯器內部,列表就像C中的陣列而不是連結結構。

常見的列表常量和操作:

為了得到更全面的資訊,可以查閱Python標準庫手冊,或者執行help(list),dir(list)檢視list方法的完整列表清單。

L = []                                   #一個空列表

L = [0,1,2,3]                         #四項:索引為0到3

L = ['abc' , ['def' , 'ghi']]        #巢狀的子列表

L = list('spam')                     #可迭代專案的列表

L = list(range(-4,4))             #連續整數的列表,返回值:

[-4, -3, -2, -1, 0, 1, 2, 3]

L[i]                                     #索引

L[i][j]                                  #索引的索引

L[i:j]                                   #分片

len(L)                                 #求長度

L1+L2                                #合併

L*3                                    #重複

for x in L:print (x)             #迭代

3 in L                                  #成員關係

L.append(4)                        #增長

L.extend([5,6,7])

L.insert(I,X)                        #插入

L.index(1)

L.Count(x)

L.sort()                             #索引

L.reverse()                       #反轉

del L[k]                            #方法:縮短語句

del L[k:j]

L.pop()

L.remove(2)

L[k:j] = []

L[k] = 1                           #索引賦值

L[k:j] = [4,5,6]             #分片賦值

L = [x**2 for x in range(5)]                    #列表解析

list(map(ord,'spam'))

實際應用中的列表:

由於列表是序列,支援很多與字串相同的操作。

基本列表操作:

>>> len([1,2,3])
3
>>> [1,2,3]+[4,5,6]
[1, 2, 3, 4, 5, 6]
>>> [1,2,3]*2
[1, 2, 3, 1, 2, 3]

不能將一個列表和一個字串和併到一起,除非先把字串轉換為列表或把列表轉換為字串:
>>> str([1,2])+"34"
'[1, 2]34'
>>> [1,2]+list("34")
[1, 2, '3', '4']

列表迭代和解析:

>>> 3 in [1, 2, '3', '4']
False
>>> for x in [1, 2, '3', '4']:
...     print x
... 
1
2
3
4

列表解析——通過對序列中的每一項應用一個表示式來構建一個新的列表方式:
>>> res = [c*4 for c in 'spam']
>>> res
['ssss', 'pppp', 'aaaa', 'mmmm']
等同效果的手動構建:
>>> res = []
>>> for c in 'spam':
...     res.append(c*4)
... 
>>> res
['ssss', 'pppp', 'aaaa', 'mmmm']

map——內建函式map對序列中的各項應用一個函式並把結果收集到一個新列表中
>>> list(map(abs,[-1,-2,0,1,2]))
[1, 2, 0, 1, 2]

索引、分片、矩陣

由於列表都是序列,對於列表而言,索引和分片操作和字串中基本相似——對列表進行索引的結果就是指定的偏移處的物件,對列表進行分片返回一個新列表。

>>> L = ['I','Love','Pyton']
>>> L[2]
'Pyton'
>>> L[-2]
'Love'
>>> L[1:]
['Love', 'Pyton']

矩陣(多維陣列):Python中為嵌套了子列表的列表

由於列表允許巢狀,所以有時需要多次索引操作連在一起使用。下面的例子中:使用一次索引操作得到一個巢狀的子列表,使用兩次索引得到子列表中具體的項。

>>> matrix = [[1,2,3],[4,5,6],[7,8,9]]
>>> matrix[1]
[4, 5, 6]
>>> matrix[1][1]
5
>>> matrix[2][0]

原處修改列表:

由於列表是可變的,所以支援原處修改列表的操作,而不會像字串那樣強迫建立新的拷貝。

索引、分片、賦值:

>>> L = ['I','Love','Pyton']
>>> L[1] = 'LOVE'
>>> L
['I', 'LOVE', 'Pyton']
>>> L[0:2] = ['Bob','like']
>>> L
['Bob', 'like', 'Pyton']

注意:索引和分片都是原地修改即對列表直接修改,而不是生成一個新的列表作為結果
>>> L = [1,2,3]
>>> L[2] = [4,5]
>>> L
[1, 2, [4, 5]]
>>> L[1:2] = [4,5]
>>> L
[1, 4, 5, [4, 5]]

分片賦值可以理解為兩步(但是實際情況並非如此):

1)刪除:刪除等號左邊指定的分片

2)插入:將等號右邊的物件插中的片段插入舊分片被刪除的位置

這樣可以幫助你理解為什麼插入的元素不需要與刪除的元素數目相等

列表方法呼叫:

<pre code_snippet_id="384110" snippet_file_name="blog_20140609_11_4711602" name="code" class="python" style="margin-top: 4px; margin-right: 0px; margin-bottom: 4px; margin-left: 0px; background-color: rgb(240, 240, 240); ">>>> L = ['I','love','Python']
>>> L.append('more')  #將一個單項加至列表末端,append只允許傳入單一物件;L.append(X)與L+[X]的結果</span>
                       一樣但是前者會原地修改L,後者會產生新的列表</span>
>>> L
['I', 'love', 'Python', 'more']
>>> L.sort()           #sort原地對列表進行排序,以遞增順序進行排序
>>> L
['I', 'Python', 'love', 'more']   
我們可以通過傳入關鍵字引數來修改排序行為:
>>> L = ['abc','ABD','aBe']
>>> L.sort()
>>> L
['ABD', 'aBe', 'abc']
>>> L.sort(key=str.lower)
>>> L
['abc', 'ABD', 'aBe']
>>> L = ['abc','ABD','aBe']
>>> L.sort(key=str.lower,reverse=True)
>>> L
['aBe', 'ABD', 'abc']</span>

其他方法呼叫:

sorted:

>>> sorted(L,key=str.lower,reverse=True)
['aBe', 'ABD', 'abc']
>>> sorted([x.lower() for x in L],reverse=True)  #使用列表解析在排序之前轉換為小寫
['abe', 'abd', 'abc']

extend()——在列表末端插入多個元素。

pop()——刪除一個元素。

reversed()——原地翻轉列表使用時必須包含在一個list呼叫中,因為它是一個迭代器。
<span style="font-family:Arial, Helvetica, sans-serif;"><span style="white-space: normal;"><span style="font-family:monospace;"><span style="white-space: pre;"></span></span></span></span><p style="margin-top: 4px; margin-right: 0px; margin-bottom: 4px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; "><span style="font-family:monospace;"><span style="white-space: pre; "></span></span></p><span style="font-family:monospace;"></span><pre name="code" class="python" style="margin-top: 4px; margin-right: 0px; margin-bottom: 4px; margin-left: 0px; background-color: rgb(240, 240, 240); ">>>> L = [1,2]
>>> L.extend([4,5,6])
>>> L
[1, 2, 4, 5, 6]
>>> L.pop()
6
>>> L
[1, 2, 4, 5]
>>> L.reverse()
>>> L
[5, 4, 2, 1]
>>> list(reversed(L))
[1, 2, 4, 5]



>>> L = []
>>> L.append(1)
>>> L.append(2)
>>> L
[1, 2]
>>> L.pop() #pop()方法預設值為最後一個元素
2
>>> L = ['I','Love','Pyton']
>>> L.index('Love')
1
>>> L.insert(1,'LOVE')
>>> L
['I', 'LOVE', 'Love', 'Pyton']
>>> L.remove('Love')
>>> L
['I', 'LOVE', 'Pyton']
>>> L.pop(1) #pop()方法也可以指定將刪除並返回元素的偏移
'LOVE'
>>> L
['I', 'Pyton']

其他常見列表操作:

del——列表是可變的,可以使用del語句在原處刪除某項或某片段

>>> L = ['I','Love','Pyton']
>>> del L[0]
>>> L
['Love', 'Pyton']
>>> del L[1:]
>>> L
['Love']
因為分片賦值是刪除加插入操作,所以可以通過將空列表賦值給分片來刪除列表片段

>>> L = ['I','Love','Pyton']
>>> L[1:] = []
>>> L
['I']
>>> L[0] = []
>>> L
[[]]

字典(dictionary):

除了列表以外,字典也許是Python之中最靈活的內建資料結構型別。如果把列表看作有序的物件集合,那麼就可以把字典當成無序的物件集合,他們的主要差別在於:字典中的元素是通過鍵來存取的,而不是通過偏移存取的

Python字典的主要屬性:

    通過鍵而不是偏移量來讀取——字典有時叫做關聯陣列或是散列表,通過鍵將一系列值聯絡在一起。

    任意物件的無序集合——字典中的項沒有特定順序。

    可變長、異構、任意巢狀——字典可在原處增長、縮短(無須生成一份拷貝),可以包含任何型別物件,支援任意深                                            度巢狀。

    屬於可變對映型別——通過索引賦值,字典可在原處修改。

    物件引用表——字典支援鍵讀取的無序物件引用表,列表則支援位置讀取的物件引用陣列。

常見字典常量和操作:

該例總結了一些具有代表性的字典操作(檢視庫手冊或者執行dir(dict)——{使用dir獲取模組內部可用變數名的列表}或是help(dict)可以得到完整的清單,型別名為dict)。當寫成常量表達式時,字典以一系列"鍵:值(key:value)"形式出現,用逗號隔開,大括號括起來。一個空字典就是一對大括號,字典可以作為另一個字典的(列表、元組)中的某一個值被巢狀

>>> D = {} #空字典

>>> D = {'spam':2,'eggs':3} #兩專案字典

>>> D = {'food':{'ham':1,'eggs':2}} #巢狀

>>> D = dict.fromkeys(['a','b']) #其他構造技術

>>> D = dict(zip(keylist,valslist)) #關鍵字、對應的對、鍵列表

>>> D = dict(name='Bob',age=42)

>>> D['eggs'] #以鍵進行索引運算

>>> D['food']['ham']

>>> 'eggs' in D #鍵存在測試

>>>D.keys #方法:鍵

>>>D.values#方法:值

>>>D.items #方法:鍵+>>>D.copy#方法:副本

>>>D.get(key,values)#方法:預設

>>>D.update(D2)#合併

>>>D.pop(key) #刪除等

>>>len(D) #長度

>>>D[key] = 42 #新增/修改 鍵,刪除鍵

>>>delD[key] #根據鍵刪除條目

>>>list(D.keys()) #字典檢視(Python 3.0

>>>D1.keys() & D2.keys()

>>>Dictionary views (Python 3.0)

>>>D = {x: x*2 for x in range(10)} #字典解析(Python 3.0

實際應用中的字典:

字典通過鍵進行索引,被巢狀的字典是通過一系列的索引表示的,當Python建立字典時,會按照任意所選,從左到右的順序來儲存項,為了取值需要提供鍵。

字典的基本操作:

>>> D = {'spam':2,'ham':1,'eggs':3}
>>> D['spam']
2
>>> D
{'eggs': 3, 'ham': 1, 'spam': 2}

注意:本例中最後的輸出和原先設定的順序不同。這樣設計的目的是為了快速進行鍵查詢(也就是雜湊查詢),鍵需在記憶體中隨機設定這裡就是為什麼假設從左到右的順序操(例如:分片和合並)作不適合字典,在字典中只能用鍵進行取值,而不是用位置進行取值
>>> len(D)                   #返回keys列表長度或字典中元素數目
3
>>> 'ham' in D               #測試鍵是否存在
True
>>> list(D.keys())           #建立關於key的列表
['eggs', 'ham', 'spam']


原處修改字典:

字典是可變的因此可以在原處對其進行修改,擴充套件,縮短而不需要生成新的字典

簡單的一個賦值就可以生成或者改變元素。

>>> D
{'eggs': 3, 'ham': 1, 'spam': 2}
>>> D['ham'] = ['I','am','wy']          #改變鍵值對應的valus
>>> D
{'eggs': 3, 'ham': ['I', 'am', 'wy'], 'spam': 2}
>>> del D['eggs']                 #通過鍵值刪除values
>>> D
{'ham': ['I', 'am', 'wy'], 'spam': 2}
>>> D['new'] = 'apple'            #增加新的values 為 apple,key為'new'
>>> D
{'new': 'apple', 'ham': ['I', 'am', 'wy'], 'spam': 2}

注意:在列表中Python會將超出列表末尾的偏移視為越界並報錯,所以在列表中需要使用append方法或分片賦值來實現,但是在字典中可以對新的字典鍵進行賦值,而不需要考慮上述問題

其他字典方法:

Eg:

字典的values和items方法分別返回字典的值列表和(key,values)對元組。

>>> D = {'spam':2,'ham':1,'eggs':3}
>>> list(D.values())
[3, 1, 2]
>>> list(D.items())
[('eggs', 3), ('ham', 1), ('spam', 2)]

上述方法在逐項遍歷字典項的迴圈中是很有效的。讀取不存在的鍵會出錯,鍵不存在時通過get的方法會返回預設值(None或使用者定義的預設值)。這是當鍵不存在時為了避免missing-key錯誤而填入預設值的一個方法:
>>> D.get('spam')
2
>>> print D.get('new')
None
>>> D.get('new',12)
12

字典的update方法有點類似於合併,但是它和從左到右的順序無關(再一次強調,字典中沒有這樣的事情)。
>>> D = {'spam':2,'ham':1,'eggs':3}
>>> D2 = {'new':4,'name':6}
>>> D.update(D2)
>>> D
{'new': 4, 'eggs': 3, 'ham': 1, 'name': 6, 'spam': 2}

把一個字典的鍵值合併到另一個字典中時會有覆蓋鍵值的情況存在:
>>> D = {'spam':2,'ham':1,'eggs':3}
>>> D2 = {'new':4,'eggs':6}
>>> D.update(D2)
>>> D
{'new': 4, 'eggs': 6, 'ham': 1, 'spam': 2}

字典的pop方法能從字典中刪除一個鍵並返回他的值(和列表的pop方法區別在於刪除的是鍵而不是一個可選位置):
>>> D = {'new': 4, 'eggs': 3, 'ham': 1, 'name': 6, 'spam': 2}
>>> D
{'new': 4, 'eggs': 3, 'spam': 2, 'ham': 1, 'name': 6}
>>> D.pop('new')
4
>>> D
{'eggs': 3, 'spam': 2, 'ham': 1, 'name': 6}
>>> L = ['aa','bb','cc','dd']
>>> 
>>> L.pop()
'dd'
>>> L.pop(1)
'bb'
>>> L
['aa', 'cc']

元組:

元組——無法修改的物件的集合。

元組由簡單的物件構成,與列表相似,之不過元組不能在原處修改(它們是不可變的),通常寫成圓括號中的一系列項。元組不支援任何方法呼叫,但是具有列表的大多數屬性。

元組的屬性:

任意物件的有序集合——元組是一個位置有序的物件集合。

通過偏移存取——在元組中的元素通過偏移訪問。

屬於不可變資料型別——元組是不可變的,不支援任何原處修改操作。

固定長度、異構、任意巢狀——因為元組是不可變的,在不生成一個拷貝的情況下不能增長或縮短。

物件引用的陣列——元組可以看成物件引用的陣列。

常見元組常量和運算:

()                                    #空元組

T = (0,)                         #單個元素的元組,非表示式

T = (0,'Ni',1.2,3)        #四個元素的元組

T = 0,'Ni',1.2,3         #四個元素的元組,與上述元組等價

T = ('abc',('def','ghi'))    #巢狀元組

T = tuple('spam')            #一個可迭代物件的項的元組

T[i]                                #索引

T[i][j]                             #索引的索引

T[i:j]                              #分片

len(T)                            #長度

T1 + T2                        #合併

T1 * 3                           #重複

for X in T: print (x)        #迭代,成員關係

'spam' in T

[x**2 for x in T]

T.index('Ni')                  #搜尋

T.count('Ni')                  #計數

實際應用中的元組:

元組沒有方法(例如,append()方法在元組是不可用的),然而元組支援字串和列表的一般序列操作。

>>> (1,2)+(3,4)
(1, 2, 3, 4)
>>> (1,2)*3
(1, 2, 1, 2, 1, 2)
>>> T = (1,2,3,4)
>>> T[0]
1
>>> T[1:]
(2, 3, 4)

元組的特殊語法:逗號和圓括號

注意:因為圓括號可以把表示式括起來,如果圓括號裡的單一物件是元組物件而不是簡單的表示式,需要對Python進行特別說明。如果確實想得到一個元組,只需要在單個元素之後,關閉括號之前加上一個逗號就可以了。

>>> X = (40)
>>> X
40
>>> Y = (40,)
>>> Y
(40,)

作為特殊情況,在不引起語法衝突的情況下,Python允許忽略元組的圓括號。

在賦值語句中,即使沒有圓括號,Python也能識別出這是一個元組:

>>> X = 1,2,3,4
>>> X
(1, 2, 3, 4)

圓括號有助於增加指令碼的可讀性。但是在元組作為常量傳遞給函式呼叫以及元組在Python2.X的print語句中列出的情況下是必不可少的,其他情況根據自己編碼愛好可有可無。

轉換、方法、不可變性:

除了常量語法不同以外,元組的操作與字串及列表是一致的。注意:+、*、分片操作在用於元祖中時將返回新元組,並且元組不提供字串、列表和字典中的方法。

例如:對元組進行排序操作,通常先將其轉換成一個可變物件,才能獲得使用排序方法呼叫的許可權或者使用新的sorted方法,他接受任何序列物件。

>>> tmp
['cc', 'aa', 'dd', 'bb']
>>> tmp.sort()
>>> tmp
['aa', 'bb', 'cc', 'dd']
>>> T = tuple(tmp)         #將tmp初始化為元組
>>> T
('aa', 'bb', 'cc', 'dd')
>>> T = ('cc','aa','dd','bb')
>>> sorted(T)
['aa', 'bb', 'cc', 'dd']
列表解析也可以用於元組轉換。

由元組生成的列表每一項都加上20:

>>> T = (1,2,3,4,5) 
>>> L = [x+20 for x in T]
>>> L
[21, 22, 23, 24, 25]

注:列表解析是名副其實的序列操作——他們總會建立新列表,但也可以用於遍歷包括元組、字串、以及其他列表在內的任何序列序列上,列表解析還可以用在某些並非實際儲存的序列之上—任何可遍歷的物件都可以,包括可自動逐行讀取的檔案。

儘管元組的方法和列表字串不同,但是元組在Python2.6和3.0中有兩個自己的方法——index和count:

>>> T = (1,2,3,2,4,2) 
>>> T.index(2)
1
>>> T.index(2,2)
3
>>> T.count(2)
3

注意:元組的不可變性只適用於元組本身頂層,而並非其內容
>>> T = (1,[2,3],4) 
>>> T
(1, [2, 3], 4)
>>> T[1]
[2, 3]
>>> T[1] = 'love'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> T[1][0] = 'love'
>>> T
(1, ['love', 3], 4)
>>> T[0] = 'I'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

對於多數程式而言,這種單層深度的不可變性對一般元組角色已經足夠了。

為什麼有了列表還要有元組:

元組的不可變性提供了某種完整性,這樣可以確保元組在程式中不會被另一個引用修改,而列表就沒有這樣的保證,因此,元組的角色類似於其他語言中的“常量”宣告。然而,這種常數概念在Python中是與物件結合的,而不是變數。

檔案:

檔案物件——計算機上外部檔案的介面,處理檔案常用的並且全能的工具。

檔案:計算機中由作業系統管理的具有名字的儲存區域。

Python檔案物件——提供一種可以存取Python程式內部檔案的方法。

簡而言之:內建open函式會建立一個Python檔案物件,可以作為計算機上的一個連結。在呼叫open之後,可以通過呼叫返回檔案物件的方法讀寫相關外部檔案。

與我們之前見過的型別相比,檔案物件多少有些不一樣。它們不是數字、序列也不是對應。相反,檔案物件只是常見檔案處理任務輸出模組。

常見檔案操作:

output = open(r'filename','w')                             #建立輸出檔案('w'表示寫入

input = open('filename','r')                                  #建立輸入檔案('r'表示讀寫

input = open('filename')                                      #同上'r'為預設值

aString = input.read()                                         #把整個檔案獨進單一字串

aString = input.read(N)                                       #讀取之後的N個位元組到一個字串

aString = input.readline()                                    #讀取下一行(包括行末識別符號)到一個字串

aList =  input.readlines()                                      #讀取整個檔案到字串列表

output.write(aString)                                           #寫入位元組字串到檔案

output.writelines(aList)                                        #把列表內所有的字串寫入檔案

output.close()                                                      #手動關閉檔案

output.flush()                                                       #把輸出緩衝區刷到硬碟中,但不關閉檔案

anyFile.seek(N)                                                    #修改檔案位置到偏移量N處以便進行下一個操作

for line in open('filename'): use line                       #檔案迭代器,一行一行的讀取檔案

open('f.txt',encoding='latin-1')                               #Python 3.0 unicode檔案

open('f.bin','rb')                                                     #Python 3.0 二進位制byte檔案

開啟檔案:

為了開啟一個檔案,程式會呼叫內建open函式,首先是外部名,接著是處理模式。

模式:

r(預設值):為輸入開啟檔案

w:為輸出並開啟檔案

a:為在檔案尾部追加內容而開啟檔案

在模式字串尾部加上b可以進行二進位制資料處理,加上+表示同時為輸入和輸出開啟檔案。

使用檔案:

一旦存在一個檔案物件,就可以呼叫其方法來讀寫相關的外部檔案。任何情況下,Python程式的中的文字檔案都採取字串形式。讀取檔案時會返回字串形式的文字,我文字作為字串傳遞給write方法。

基礎用法: 檔案迭代器是最好的讀取行工具;

                從檔案讀取資料到指令碼時是一個字串,如果字串不是你所需,就需要轉換型別;

                close是通常選型;

                檔案是緩衝的並且是可查詢的;

參考:Python學習手冊