由於我剛開始學習Python時,被序列結構轉暈了,所以寫了這篇博客。
字典
導言
隨便翻開一本英語單詞書,你就會看到這樣的畫面:
我們能觀察到,這頁單詞書的排版方式是左邊一個單詞,右邊是它的意思,單詞和意思是相互對應的,這種排版方式可以幫助我們很好地理解字典結構。
什么是字典
字典是一系列鍵——值對。每個鍵都與一個值相關聯,你可以使用鍵來訪問與之相關聯的值。與鍵相關聯的值可以是任意Python對象,包括數字、字符串、列表和字典。
字典用放在花括號“{ }”的一系列鍵——值對表示,每個元素都包含“鍵”和“值”,“鍵”和“值”之間用冒號分隔,相鄰兩個元素用逗號分隔。在字典中,你可以存儲任意數量的鍵——值對。例如以我的期末考試成績創建一個字典:
my_grade = {'C language': 39, 'English': 19,'math': 29 ,'modern history': 95}
print(my_grade)
輸出結果:
{'C language': 39, 'English': 19,'math': 29 ,'modern history': 95}
- Pyhton的字典結構相當於Java或C++語言中的Map對象。
字典的主要特征
- 字典通過踺而不是通過索引來讀取:字典有時也稱為關聯數組或者散列表。它是通過鍵將一系列的值聯系起來的,這樣就可以通過鍵從字典中獲取指定項,但不能通過索引來獲取。
- 字典是任意對象的無序集合:字典是無序的,各項是從左到右隨機排序的,即保存在字典中的項沒有特定的順序,這樣可以提高查找順序。
- 字典是可變的,可以任意嵌套:字典可以在原處增長或者縮短(無須生成一拷貝),並且它支持任意深度的嵌套(即它的值可以是列表或者其他的字典)。
- 字典中的鍵必須唯一:不允許同一個鍵出現兩次,如果出現兩次,則后一個值會被記住。
- 字典中的鍵必須不可變:字典中的鍵是不可變的,所以可以使用數字、字符串或者元組,但不能使用列表。
訪問字典的值
想要訪問與鍵相對應的值,可依次指定字典名和放在方括號內的鍵,可以用列表的索引來類比,只不過這里的索引是“鍵”,例如:
my_grade = {'C language': 39, 'English': 19,'math': 29 ,'modern history': 95}
print(my_grade['C language'])
Python將返回字典中與鍵相對應的值,輸出結果為:
39
創建空字典並添加鍵——值對
和列表類似,字典是一個動態結構,我們可以隨時在其中添加鍵——值對。添加鍵——值對時,需要依次指定字典名、用方括號括起來的鍵和對應的值。在實際應用當中經常需要先建立一個空字典,例如我們需要集成用戶輸入的數據,然后再依次把鍵——值對添加到字典當中,例如:
my_grade = {} #建立空字典
my_grade['C language'] = 39
my_grade['English'] = 19
my_grade['math'] = 29
my_grade['modern history'] = 95
print(my_grade)
輸出結果:
{'C language': 39, 'English': 19,'math': 29 ,'modern history': 95}
修改字典中的值
修改字典中的值的寫法與添加鍵值對的寫法相同,也是需要依次指定字典名、用方括號括起來的鍵和對應的新值。例如:
my_grade = {'C language': 60, 'English': 19,'math': 29 ,'modern history': 95}
my_grade['C language'] = 39
print(my_grade)
輸出結果:
{'C language': 39, 'English': 19,'math': 29 ,'modern history': 95}
刪除鍵——值對
使用del語句刪除字典中的鍵——值對,使用時要指定字典名和要刪除的鍵。例如:
my_grade = {'C language': 39, 'English': 19,'math': 29 ,'modern history': 95, 'PE' : 0}
del my_grade['PE']
print(my_grade)
輸出結果:
{'C language': 39, 'English': 19,'math': 29 ,'modern history': 95}
遍歷字典
遍歷所有鍵——值對
當我們想要遍歷鍵——值對時,由於鍵和值會被我們同時遍歷,所以需要分別定義兩個變量來存儲。同時我們還需要使用“.items()”方法,該方法以列表返回可遍歷的(鍵, 值) 元組數組,語法為:
dict.items()
參數 | 說明 |
---|---|
dict | 需要被操作的字典 |
為了直觀地看出.items()方法的作用,我們寫一段代碼來看看:
my_grade = {'C language': 39, 'English': 19,'math': 29 ,'modern history': 95}
print(my_grade.items())
輸出結果為:
my_grade([('C language', 39), ('English', 19), ('math', 29), ('modern history', 95)])
我們還是使用for 循環結構來遍歷字典:
my_grade = {'C language': 39, 'English': 19,'math': 29 ,'modern history': 95}
for key, value in my_grade.items():
print("Key: " + key)
print("Value: ",value,"\n")
遍歷時,“.items()”方法返回的鍵——值對列表,會被依次存儲進我們定義分別用來存儲鍵和值的變量中。輸出結果為:
Key: C language
Value: 39
Key: English
Value: 19
Key: math
Value: 29
Key: modern history
Value: 95
- Python不關心鍵——值對的存儲順序,而只跟蹤鍵和值之間的關聯關系。
遍歷字典中的鍵
在不需要使用字典的值的時候,我們使用“.key()”方法,該方法返回一個可迭代對象,可以使用 list() 來轉換為列表。語法為:
dict.keys()
參數 | 說明 |
---|---|
dict | 需要被操作的字典 |
為了直觀地看出.key()方法的作用,我們寫一段代碼來看看:
my_grade = {'C language': 39, 'English': 19,'math': 29 ,'modern history': 95}
print(list(my_grade.keys()) )
輸出結果為:
['C language', 'English', 'math', 'modern history']
我們還是使用for 循環結構來遍歷字典:
my_grade = {'C language': 39, 'English': 19,'math': 29 ,'modern history': 95}
for key in my_grade.keys():
print("Key: " + key)
輸出結果:
Key: C language
Key: English
Key: math
Key: modern history
其實當我們遍歷字典時,會默認遍歷字典中的所有鍵,所以你把代碼寫成這樣子,輸出的內容是一樣的:
my_grade = {'C language': 39, 'English': 19,'math': 29 ,'modern history': 95}
for key in my_grade:
print("Key: " + key)
遍歷字典中的值
使用“.values()”方法,該方法返回一個迭代器,可以使用 list() 來轉換為列表,列表為字典中的所有值,語法為:
dict.values()
參數 | 說明 |
---|---|
dict | 需要被操作的字典 |
為了直觀地看出.key()方法的作用,我們寫一段代碼來看看:
my_grade = {'C language': 39, 'English': 19,'math': 29 ,'modern history': 95}
print(list(my_grade.values()) )
輸出結果為:
[39, 19, 29, 95]
我們還是使用for 循環結構來遍歷字典:
my_grade = {'C language': 39, 'English': 19,'math': 29 ,'modern history': 95}
for value in my_grade.values():
print("Values: ",value)
輸出結果為:
Values: 39
Values: 19
Values: 29
Values: 95
通過映射函數創建字典
首先我們認識一下zip()函數,,該函數用於將可迭代的對象作為參數,例如多個列表或元組,將對象中對應的元素組合為元組,然后返回組成的列表。如果各個迭代器的元素個數不一致,則返回列表長度與最短的對象相同,利用 * 號操作符,可以將元組解壓為列表。語法為:
zip([iterable, ...])
參數 | 說明 |
---|---|
iterable | 一個或多個迭代器 |
利用zip()函數創建字典的語法為:
dictionary = dict(zip(list1,list2))
參數 | 說明 |
---|---|
dictionary | 要創建的字典名稱 |
list1 | 表示一個用於指定要生成字典的鍵的列表 |
list2 | 表示一個用於指定要生成字典的值的列表 |
- 如果list1 和 list2 的長度不同,則字典與最短的列表長度相同。
我們試着用這種寫法創建一個字典:
subject = ['C language', 'English','math' ,'modern history']
grade = [39, 19, 29, 95]
my_grade = dict(zip(subject, grade))
print(my_grade)
輸出結果為:
{'C language': 39, 'English': 19, 'math': 29, 'modern history': 95}
集合
導言
看到“集合”這兩個字,你是否會想起高中被數學支配的恐懼?你猜的沒錯,Python中的集合與高中的集合概念相類似,是用於保存不重復的元素的序列結構,因此通過我們對集合在數學上的概念的理解,就能夠幫助我們明白集合機構是一個什么樣的順序結構。
什么是集合
集合是一個無序的不重復元素序列,集合是可變序列,可以使用大括號 { } 或者 set() 函數創建集合,如果想要創建一個空集合,則必須用 set(),因為 { } 會被認為是創建一個空字典例如:
Subject = {'Chinese', 'Mathematics', 'English', 'Physics', 'Chemistry', 'Biology'}
print(Subject)
輸出結果為:
{'Chemistry', 'Biology', 'Physics', 'Mathematics', 'Chinese', 'English'}
- Python中的集合是無序的,因此每次輸出的排列順序可能會不同。
集合中每個元素是唯一的,針對這個特點,我們寫一段代碼來證明一下:
Subject = {'Chinese', 'Mathematics', 'English', 'Chinese', 'Mathematics', 'English'}
print(Subject)
輸出結果為:
{'English', 'Chinese', 'Mathematics'}
由此可見,Python對於集合中重復的元素只會保留一個。
set()函數
set() 函數創建一個無序不重復元素集,返回值為新的集合對象。語法為:
a_set = set([iterable])
參數 | 說明 |
---|---|
a_set | 要創建的集合名稱 |
iterable | 可迭代對象對象 |
例如:
Subject = set(['Chinese', 'Mathematics', 'English', 'Physics', 'Chemistry', 'Biology'])
計算集合元素個數
使用len()函數,該函數將返回對象(字符、列表、元組等)長度或項目個數。語法為:
len( s )
參數 | 說明 |
---|---|
s | 對象 |
集合添加、刪除元素
添加元素
使用“.add()”方法,該方法用於給集合添加元素,無返回值,如果添加的元素在集合中已存在,則不執行任何操作。語法為:
set.add(elmnt)
參數 | 說明 |
---|---|
set | 要創建的集合名稱 |
elmnt | 要添加的元素 |
例如:
Subject = {'Chinese', 'Mathematics', 'English', 'Physics', 'Chemistry'}
Subject.add('Biology')
print(Subject)
Subject.add('Biology') #該語句不產生任何操作
print(Subject)
輸出結果為:
{'Mathematics', 'Chinese', 'Biology', 'English', 'Chemistry', 'Physics'}
{'Mathematics', 'Chinese', 'Biology', 'English', 'Chemistry', 'Physics'}
刪除元素
隨機移除元素
使用pop()方法,該方法用於隨機移除一個元素,返回值為移除的元素。語法為:
set.pop()
參數 | 說明 |
---|---|
set | 要操作的集合 |
例如:
Subject = {'Chinese', 'Mathematics', 'English', 'Physics', 'Chemistry', 'Biology'}
x = Subject.pop()
print(Subject,x)
輸出結果為:
{'Physics', 'Mathematics', 'Biology', 'English', 'Chemistry'} Chinese
指定移除元素
remove() 方法或discard() 方法,這兩種方法都用於移除集合中的指定元素。不同點在於remove()方法在移除一個不存在的元素時會發生錯誤,且會返回被刪除的元素,而discard()方法不會。語法為:
set.discard(value)
set.remove(value)
參數 | 說明 |
---|---|
set | 要操作的集合 |
value | 要移除的元素 |
例如:
Subject = {'Chinese', 'Mathematics', 'English', 'Physics', 'Chemistry'}
Subject.discard('Physics')
Subject.remove('Chemistry')
print(Subject)
輸出結果為:
{'Mathematics', 'Chinese', 'English'}
刪除、清空集合
刪除整個集合
使用del語句刪除整個集合,語法為:
Subject = {'Chinese', 'Mathematics', 'English', 'Physics', 'Chemistry', 'Biology'}
del Subject
清空集合
使用clear()方法,該方法用於移除集合中的所有元素。語法為:
set.clear()
參數 | 說明 |
---|---|
set | 要操作的集合 |
例如:
Subject = {'Chinese', 'Mathematics', 'English', 'Physics', 'Chemistry', 'Biology'}
Subject.clear()
print(Subject)
輸出結果為:
set()
集合的交集、並集和差集運算
運算符進行運算
集合進行交集運算時使用“&”符號,進行並集運算時使用“|”符號:進行差集運算時使用“-”符號,進行對稱差集運算時使用“^”符號。例如:
Subject1 = {'Chinese', 'Mathematics', 'English', 'Physics', 'Chemistry', 'Biology'}
Subject2 = {'Chinese', 'Mathematics', 'English', 'History', 'geography', 'Politics'}
print(Subject1 & Subject2) #交集運算
print(Subject1 | Subject2) #並集運算
print(Subject1 - Subject2) #差集運算
print(Subject1 ^ Subject2) #對稱差集運算
輸出結果為:
{'English', 'Chinese', 'Mathematics'}
{'Chinese', 'Chemistry', 'Politics', 'geography', 'Biology', 'Physics', 'Mathematics', 'English', 'History'}
{'Biology', 'Chemistry', 'Physics'}
{'Biology', 'Chemistry', 'Physics', 'Politics', 'History', 'geography'}
函數實現
函數 | 功能 |
---|---|
intersection() | 返回集合的交集 |
difference() | 返回多個集合的差集 |
union() | 返回兩個集合的並集 |
例題講解
題目選擇於PTA題庫。
四則運算(用字典實現
輸入樣例:
7
/
3
輸出樣例:
2.33
- 本題出現除零異常時,要輸出提示信息“divided by zero”
題目分析
拿到這道題,我們的第一反應應該是來個多分支結構,然后根據運算符的不同進入不同的分支。這么做當然可以,但是題目要求用字典實現,這就很令人苦惱了。
類比C語言的“switch”多分支結構,我們可以通過常量表達式,直接進入不同的分支,這與字典有所相同之處。字典的鍵就與“switch”結構的常量表達式有相同的地方,我們訪問字典中的值都是通過鍵來訪問的,針對這道題,我們只需要讓字典中訪問的值是一個運算式,即可實現題目的要求。別忘了這道題要異常處理,要try一下。
代碼實現
列表去重
輸入樣例:
[4,7,5,6,8,6,9,5]
輸出樣例:
4 7 5 6 8 9
題目分析:
如果這題是出在C語言的題集,那我們得花上好一會才能解決。然而我們現在用的是Python,思路是很明確的,我們直接把這個列表轉成集合,直接一步到位。
但是此時解題還沒有結束,因為題目要求按原來次序輸出,大家可以試試看,轉換成集合之后輸出的順序是隨機的,就算我們轉回了列表,里面元素的順序已經不是原來的順序了。解決方法是在列表去重之前,先保存一個副本,然后將去重后的列表按照去重前的列表為規則排序,再輸出。
所以這道題真正的難點是按原來的次序給列表排序(笑)!
代碼實現
通過兩個列表構建字典
輸入樣例
學校 城市 郵編
集美大學 廈門 361021
輸出樣例
[('城市', '廈門'), ('學校', '集美大學'), ('郵編', '361021')]
題目分析:
思路是很自然的,我們給輸入的兩行數據分割一下,轉成列表,然后用映射函數建立字典即可。如果你用一個for循環結構來建立也可以。
代碼實現
jmu-python-重復元素判定
輸入樣例
5
1 2 3 4 5
1 3 2 5 4
1 2 3 6 1
1 2 3 2 1
1 1 1 1 1
輸出樣例
True=3, False=2
題目分析
如果這道題拿到C語言里面的話,那又是一件很麻煩的事情了,我們會用循環一個一個比較。但是在Python我們有集合結構,思路是很自然的,我們拷貝一份輸入的列表,然后轉換成集合,把這兩個的長度進行比較,即可得知是否含有重復的元素了。
代碼實現
jmu-python-統計投票數
輸入樣例:
3
Mike Alan Lucy
Mike Lily Meg
Lily Mike Meg Lily
輸出樣例
[('Mike', 3), ('Lily', 2), ('Meg', 2), ('Lucy', 1), ('Alan', 1)]
題目分析:
我們要統計每個人的投票數,那么每個候選人和得票數是一個對應關系,因此我們優先選擇字典結構來解決這個問題。我們先建立一個空字典,字典的鍵是候選人,值是得票數,然后遍歷單個投票名單,如果候選人出現過就讓對應的值加1,如果沒有出現過,就添加一個新的鍵,對應的值為數值1。
由於一行候選人可能會有重復出現的情況,因此輸入的數據應該轉成集合,過濾一下重復的候選人。輸出的時候以得票數為規則降序排序一下字典即可。
代碼實現:
jmu-Java&Python-統計文字中的單詞數量並按出現次數排序
輸入樣例
failure is probably the fortification in your pole
it is like a peek your wallet as the thief when you
are thinking how to spend several hard-won lepta
when you are wondering whether new money it has laid
background because of you then at the heart of the
most lax alert and most low awareness and left it
godsend failed
!!!!!
輸出樣例
46
the=4
it=3
you=3
and=2
are=2
is=2
most=2
of=2
when=2
your=2
題目分析
這道題表面上很難,其實是唬人的,一個單詞和它的出現次數是一個對應的關系,因此我們優先考慮使用字典結構。先建立一個空字典,然后以單詞作為鍵,出現此處作為值,單詞沒多出現一次值就加1即可完成。
因此這道題的難點其實是在於文段的准確讀入,我們先建立一個空字符串,每次讀入一行文字,然后把標點符號用“replace()”方法替換為空格,把所有單詞轉換為小寫。讀取完畢后以空格為分隔符分割字符串,在進行統計操作即可。別忘了輸出的時候要以“次數按照降序排序,如果次數相同,則按照鍵值的字母升序排序”為規則排序。
代碼實現
參考資料
《Python從入門到精通》————明日科技,清華大學出版社
《Python編程從入門到實踐》————[美]Eric Matthes 著,袁國忠 譯,人民郵電出版社
菜鳥教程