2020年9月21日星期一

006 Python编程 從入門到實踐 第一部分 基礎知識 第 6 章 字典

 申明本站飛宇網 https://feiyetopro.blogspot.com/自網路收集整理之書籍文章影音僅供預覽交流學習研究,其[書籍、文章、影音]情節內容, 評論屬其個人行為, 與本網站無關。版權歸原作者和出版社所有,請在下載 24 小時內刪除,不得用作商業用途;如果您喜歡其作品,請支持訂閱購買[正版]謝謝!




6 章 字典

在本章中,你將學習能夠將相關資訊關聯起來的Python字典。你將學習如何訪問和修改字典中的資訊。鑒於字典可存儲的信息量幾乎不受限制,因此我們會演示如何遍歷字典中的資料。另外,你還將學習存儲字典的清單、存儲清單的字典和存儲字典的字典。

理解字典後,你就能夠更準確地為各種真實物體建模。你可以創建一個表示人的字典,然後想在其中存儲多少資訊就存儲多少資訊:姓名、年齡、地址、職業以及要描述的任何方面。你還能夠存儲任意兩種相關的資訊,如一系列單詞及其含義,一系列人名及其喜歡的數字,以及一系列山脈及其海拔等。

6.1 一個簡單的字典

來看一個遊戲,其中包含一些外星人,這些外星人的顏色和點數各不相同。下面是一個簡單的字典,存儲了有關特定外星人的資訊:

alien.py

 

alien_0 = {'color': 'green', 'points': 5}

 

print(alien_0['color'])

print(alien_0['points'])

 

 

 

 

 

 

 

 

字典alien_0 存儲了外星人的顏色和點數。使用兩條print 語句來訪問並列印這些資訊,如下所示:

 

green

5

 

 

 

 

 

 

 

 

與大多數程式設計概念一樣,要熟練使用字典,也需要一段時間的練習。使用字典一段時間後,你就會明白為何它們能夠高效地模擬現實世界中的情形。

6.2 使用字典

Python中,字典 是一系列值對 。每個 都與一個值相關聯,你可以使用鍵來訪問與之相關聯的值。與鍵相關聯的值可以是數位、字串、清單乃至字典。事實上,可將任何Python物件用作字典中的值。

Python中,字典用放在花括弧{} 中的一系列鍵值對表示,如前面的示例所示:

 

alien_0 = {'color': 'green', 'points': 5}

 

 

 

 

 

 

 

 

 對是兩個相關聯的值。指定鍵時,Python將返回與之相關聯的值。鍵和值之間用冒號分隔,而鍵值對之間用逗號分隔。在字典中,你想存儲多少個鍵值對都可以。

最簡單的字典只有一個鍵值對,如下述修改後的字典alien_0 所示:

 

alien_0 = {'color': 'green'}

 

 

 

 

 

 

 

 

這個字典只存儲了一項有關alien_0 的資訊,具體地說是這個外星人的顏色。在這個字典中,字串'color' 是一個鍵,與之相關聯的值為'green' 

6.2.1 訪問字典中的值

要獲取與鍵相關聯的值,可依次指定字典名和放在方括號內的鍵,如下所示:

 

alien_0 = {'color': 'green'}

print(alien_0['color'])

 

 

 

 

 

 

 

 

這將返回字典alien_0 中與鍵'color' 相關聯的值:

 

green

 

 

 

 

 

 

 

 

字典中可包含任意數量的鍵值對。例如,下面是最初的字典alien_0 ,其中包含兩個鍵值對:

 

alien_0 = {'color': 'green', 'points': 5}

 

 

 

 

 

 

 

 

現在,你可以訪問外星人alien_0 的顏色和點數。如果玩家射殺了這個外星人,你就可以使用下面的代碼來確定玩家應獲得多少個點:

 

  alien_0 = {'color': 'green', 'points': 5}

 

new_points = alien_0['points']

print("You just earned " + str(new_points) + " points!")

 

 

 

 

 

 

 

 

上述代碼首先定義了一個字典,然後從這個字典中獲取與鍵'points' 相關聯的值(見),並將這個值存儲在變數new_points 中。接下來,將這個整數轉換為字串,並列印一條消息,指出玩家獲得了多少個點(見

 

You just earned 5 points!

 

 

 

 

 

 

 

 

如果你在有外星人被射殺時都運行這段代碼,就會獲取該外星人的點數。

6.2.2 添加鍵值對

字典是一種動態結構,可隨時在其中添加鍵值對。要添加鍵值對,可依次指定字典名、用方括號括起的鍵和相關聯的值。

下面在字典alien_0 中添加兩項資訊:外星人的 x 座標和 y 座標,讓我們能夠在螢幕的特定位置顯示該外星人。我們將這個外星人放在螢幕左邊緣,且離螢幕上邊緣25圖元的地方。由於螢幕坐標系的原點通常為左上角,因此要將該外星人放在螢幕左邊緣,可將 x 座標設置為0;要將該外星人放在離螢幕頂部25圖元的地方,可將 y 座標設置為25,如下所示:

 

  alien_0 = {'color': 'green', 'points': 5}

  print(alien_0)

 

alien_0['x_position'] = 0

alien_0['y_position'] = 25

  print(alien_0)

 

 

 

 

 

 

 

 

我們首先定義了前面一直在使用的字典,然後列印這個字典,以顯示其資訊快照。在處,我們在這個字典中新增了一個鍵值對,其中的鍵為'x_position' ,而值為0 。在處,我們重複這樣的操作,但使用的鍵為'y_position' 。列印修改後的字典時,將看到這兩個新增的鍵值對:

 

{'color': 'green', 'points': 5}

{'color': 'green', 'points': 5, 'y_position': 25, 'x_position': 0}

 

 

 

 

 

 

 

 

這個字典的最終版本包含四個鍵值對,其中原來的兩個指定外星人的顏色和點數,而新增的兩個指定位置。注意,鍵值對的排列順序與添加順序不同。Python不關心鍵值對的添加順序,而只關心鍵和值之間的關聯關係。

6.2.3 先創建一個空字典

有時候,在空字典中添加鍵值對是為了方便,而有時候必須這樣做。為此,可先使用一對空的花括弧定義一個字典,再分行添加各個鍵值對。例如,下例演示了如何以這種方式創建字典alien_0 

 

alien_0 = {}

 

alien_0['color'] = 'green'

alien_0['points'] = 5

 

print(alien_0)

 

 

 

 

 

 

 

 

這裡首先定義了空字典alien_0 ,再在其中添加顏色和點數,得到前述示例一直在使用的字典:

 

{'color': 'green', 'points': 5}

 

 

 

 

 

 

 

 

使用字典來存儲使用者提供的資料或在編寫能自動生成大量鍵值對的代碼時,通常都需要先定義一個空字典。

6.2.4 修改字典中的值

要修改字典中的值,可依次指定字典名、用方括號括起的鍵以及與該鍵相關聯的新值。例如,假設隨著遊戲的進行,需要將一個外星人從綠色改為黃色:

 

alien_0 = {'color': 'green'}

print("The alien is " + alien_0['color'] + ".")

 

alien_0['color'] = 'yellow'

print("The alien is now " + alien_0['color'] + ".")

 

 

 

 

 

 

 

 

我們首先定義了一個表示外星人alien_0 的字典,其中只包含這個外星人的顏色。接下來,我們將與鍵'color' 相關聯的值改為'yellow' 。輸出表明,這個外星人確實從綠色變成了黃色:

 

The alien is green.

The alien is now yellow.

 

 

 

 

 

 

 

 

來看一個更有趣的例子:對一個能夠以不同速度移動的外星人的位置進行跟蹤。為此,我們將存儲該外星人的當前速度,並據此確定該外星人將向右移動多遠:

 

  alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'}

  print("Original x-position: " + str(alien_0['x_position']))

 

  # 向右移動外星人

  # 據外星人當前速度決定將其移動多遠

if alien_0['speed'] == 'slow':

      x_increment = 1

  elif alien_0['speed'] == 'medium':

      x_increment = 2

  else:

      # 這個外星人的速度一定很快

      x_increment = 3

 

  # 新位置等於老位置加上增量

alien_0['x_position'] = alien_0['x_position'] + x_increment

 

  print("New x-position: " + str(alien_0['x_position']))

 

 

 

 

 

 

 

 

我們首先定義了一個外星人,其中包含初始的x 座標和y 座標,還有速度'medium' 。出於簡化考慮,我們省略了顏色和點數,但即便包含這些鍵-值對,這個示例的工作原理也不會有任何變化。我們還列印了x_position 的初始值,旨在讓用戶知道這個外星人向右移動了多遠。

處,使用了一個if-elif-else 結構來確定外星人應向右移動多遠,並將這個值存儲在變數x_increment 中。如果外星人的速度為'slow' ,它將向右移動一個單位;如果速度為'medium' ,將向右移動兩個單位;如果為'fast' ,將向右移動三個單位。確定移動量後,將其與x_position 的當前值相加(見),再將結果關聯到字典中的鍵x_position 

由於這是一個速度中等的外星人,因此其位置將向右移動兩個單位:

 

Original x-position: 0

New x-position: 2

 

 

 

 

 

 

 

 

這種技術很棒:通過修改外星人字典中的值,可改變外星人的行為。例如,要將這個速度中等的外星人變成速度很快的外星人,可添加如下代碼行:

 

alien_0['speed'] = fast

 

 

 

 

 

 

 

 

這樣,再次運行這些代碼時,其中的if-elif-else 結構將把一個更大的值賦給變數x_increment 

6.2.5 刪除鍵值對

對於字典中不再需要的資訊,可使用del 語句將相應的鍵值對徹底刪除。使用del 語句時,必須指定字典名和要刪除的鍵。

例如,下面的代碼從字典alien_0 中刪除鍵'points' 及其值:

 

  alien_0 = {'color': 'green', 'points': 5}

  print(alien_0)

 

del alien_0['points']

  print(alien_0)

 

 

 

 

 

 

 

 

處的代碼行讓Python將鍵'points' 從字典alien_0 中刪除,同時刪除與這個鍵相關聯的值。輸出表明,鍵'points' 及其值5 已從字典中刪除,但其他鍵值對未受影響:

 

{'color': 'green', 'points': 5}

{'color': 'green'}

 

 

 

 

 

 

 

 

注意  刪除的鍵值對永遠消失了。

6.2.6 由類似物件組成的字典

在前面的示例中,字典存儲的是一個物件(遊戲中的一個外星人)的多種資訊,但你也可以使用字典來存儲眾多物件的同一種資訊。例如,假設你要調查很多人,詢問他們最喜歡的程式設計語言,可使用一個字典來存儲這種簡單調查的結果,如下所示:

 

favorite_languages = {

    'jen': 'python',

    'sarah': 'c',

    'edward': 'ruby',

    'phil': 'python',

    }

 

 

 

 

 

 

 

 

正如你看到的,我們將一個較大的字典放在了多行中。其中每個鍵都是一個被調查者的名字,而每個值都是被調查者喜歡的語言。確定需要使用多行來定義字典時,在輸入左花括弧後按回車鍵,再在下一行縮進四個空格,指定第一個鍵值對,並在它後面加上一個逗號。此後你再次按回車鍵時,文字編輯器將自動縮進後續鍵值對,且縮進量與第一個鍵值對相同。

定義好字典後,在最後一個鍵值對的下一行添加一個右花括弧,並縮進四個空格,使其與字典中的鍵對齊。另外一種不錯的做法是在最後一個鍵值對後面也加上逗號,為以後在下一行添加鍵值對做好準備。

注意  對於較長的清單和字典,大多數編輯器都有以類似方式設置其格式的功能。對於較長的字典,還有其他一些可行的格式設置方式,因此在你的編輯器或其他原始程式碼中,你可能會看到稍微不同的格式設置方式。

給定被調查者的名字,可使用這個字典輕鬆地獲悉他喜歡的語言:

favorite_languages.py

 

  favorite_languages = {

      'jen': 'python',

      'sarah': 'c',

      'edward': 'ruby',

      'phil': 'python',

      }

 

print("Sarah's favorite language is " +

     favorite_languages['sarah'].title() +

     ".")

 

 

 

 

 

 

 

 

為獲悉Sarah 喜歡的語言,我們使用如下代碼:

 

favorite_languages['sarah']

 

 

 

 

 

 

 

 

print 語句中,我們使用了這種語法(見);輸出指出了Sarah喜歡的語言:

 

Sarah's favorite language is C.

 

 

 

 

 

 

 

 

這個示例還演示了如何將較長的print 語句分成多行。單詞print 比大多數字典名都短,因此讓輸出的第一部分緊跟在左括弧後面是合理的(見)。請選擇在合適的地方拆分要列印的內容,並在第一行末尾(見)加上一個拼接運算子(+ )。按回車鍵進入print 語句的後續各行,並使用Tab鍵將它們對齊並縮進一級。指定要列印的所有內容後,在print 語句的最後一行末尾加上右括弧(見

動手試一試

6-1  :使用一個字典來存儲一個熟人的資訊,包括名、姓、年齡和居住的城市。該字典應包含鍵first_name last_name age city 。將存儲在該字典中的每項資訊都列印出來。

person = {

    'first_name': 'eric',

    'last_name': 'matthes',

    'age': 43,

    'city': 'sitka',

    }

 

print(person['first_name'])

print(person['last_name'])

print(person['age'])

print(person['city'])

 

 

輸出:

 

eric

matthes

43

sitka

6-2 喜歡的數位 :使用一個字典來存儲一些人喜歡的數位。請想出5個人的名字,並將這些名字用作字典中的鍵;想出每個人喜歡的一個數位,並將這些數位作為值存儲在字典中。列印每個人的名字和喜歡的數位。為讓這個程式更有趣,通過詢問朋友確保資料是真實的。

favorite_numbers = {

    'mandy': 42,

    'micah': 23,

    'gus': 7,

    'hank': 1000000,

    'maggie': 0,

    }

 

num = favorite_numbers['mandy']

print("Mandy's favorite number is " + str(num) + ".")

 

num = favorite_numbers['micah']

print("Micah's favorite number is " + str(num) + ".")

 

num = favorite_numbers['gus']

print("Gus's favorite number is " + str(num) + ".")

 

num = favorite_numbers['hank']

print("Hank's favorite number is " + str(num) + ".")

 

num = favorite_numbers['maggie']

print("Maggie's favorite number is " + str(num) + ".")

 

 

輸出:

 

Mandy's favorite number is 42.

Micah's favorite number is 23.

Gus's favorite number is 7.

Hank's favorite number is 1000000.

Maggie's favorite number is 0.

6-3 詞彙表 Python字典可用于類比現實生活中的字典,但為避免混淆,我們將後者稱為詞彙表。

·          想出你在前面學過的5個程式設計詞彙,將它們用作詞彙表中的鍵,並將它們的含義作為值存儲在詞彙表中。

·          以整潔的方式列印每個詞彙及其含義。為此,你可以先列印詞彙,在它後面加上一個冒號,再列印詞彙的含義;也可在一行列印詞彙,再使用分行符號(\n )插入一個空行,然後在下一行以縮進的方式列印詞彙的含義。

glossary = {

    'string': 'A series of characters.',

    'comment': 'A note in a program that the Python interpreter ignores.',

    'list': 'A collection of items in a particular order.',

    'loop': 'Work through a collection of items, one at a time.',

    'dictionary': "A collection of key-value pairs.",

    }

 

word = 'string'

print("\n" + word.title() + ": " + glossary[word])

 

word = 'comment'

print("\n" + word.title() + ": " + glossary[word])

 

word = 'list'

print("\n" + word.title() + ": " + glossary[word])

 

word = 'loop'

print("\n" + word.title() + ": " + glossary[word])

 

word = 'dictionary'

print("\n" + word.title() + ": " + glossary[word])

 

 

輸出:

 

String: A series of characters.

 

Comment: A note in a program that the Python interpreter ignores.

 

List: A collection of items in a particular order.

 

Loop: Work through a collection of items, one at a time.

 

Dictionary: A collection of key-value pairs.

6.3 遍歷字典

一個Python字典可能只包含幾個鍵值對,也可能包含數百萬個鍵值對。鑒於字典可能包含大量的資料,Python支援對字典遍歷。字典可用於以各種方式存儲資訊,因此有多種遍歷字典的方式:可遍歷字典的所有鍵值對、鍵或值。

6.3.1 遍歷所有的鍵值對

探索各種遍歷方法前,先來看一個新字典,它用於存儲有關網站使用者的資訊。下面的字典存儲一名使用者的用戶名、名和姓:

 

user_0 = {

    'username': 'efermi',

    'first': 'enrico',

    'last': 'fermi',

    }

 

 

 

 

 

 

 

 

利用本章前面介紹過的知識,可訪問user_0 的任何一項資訊,但如果要獲悉該使用者字典中的所有資訊,該怎麼辦呢?可以使用一個for 迴圈來遍歷這個字典:

user.py

 

  user_0 = {

      'username': 'efermi',

      'first': 'enrico',

      'last': 'fermi',

      }

 

for key, value in user_0.items():

     print("\nKey: " + key)

     print("Value: " + value)

 

 

 

 

 

 

 

 

所示,要編寫用於遍歷字典的for 迴圈,可聲明兩個變數,用於存儲鍵值對中的鍵和值。對於這兩個變數,可使用任何名稱。下面的代碼使用了簡單的變數名,這完全可行:

 

for k, v in user_0.items()

 

 

 

 

 

 

 

 

for 語句的第二部分包含字典名和方法items() (見),它返回一個值對列表。接下來,for 迴圈依次將每個鍵值對存儲到指定的兩個變數中。在前面的示例中,我們使用這兩個變數來列印每個鍵(見)及其相關聯的值(見)。第一條print 語句中的"\n" 確保在輸出每個鍵值對前都插入一個空行:

 

Key: last

Value: fermi

 

Key: first

Value: enrico

 

Key: username

Value: efermi

 

 

 

 

 

 

 

 

注意,即便遍歷字典時,鍵值對的返回順序也與存儲順序不同。Python不關心鍵值對的存儲順序,而只跟蹤鍵和值之間的關聯關係。

6.2.6節的示例favorite_languages.py中,字典存儲的是不同人的同一種資訊;對於類似這樣的字典,遍歷所有的鍵值對很合適。如果遍歷字典favorite_languages ,將得到其中每個人的姓名和喜歡的程式設計語言。由於其中的鍵都是人名,而值都是語言,因此我們在迴圈中使用變數name language ,而不是key value ,這讓人更容易明白迴圈的作用:

favorite_languages.py

 

  favorite_languages = {

      'jen': 'python',

      'sarah': 'c',

      'edward': 'ruby',

      'phil': 'python',

      }

 

for name, language in favorite_languages.items():

     print(name.title() + "'s favorite language is " +

          language.title() + ".")

 

 

 

 

 

 

 

 

處的代碼讓Python遍歷字典中的每個鍵值對,並將鍵存儲在變數name 中,而將值存儲在變數language 中。這些描述性名稱能夠讓人非常輕鬆地明白print 語句(見)是做什麼的

僅使用幾行代碼,我們就將全部調查結果顯示出來了:

 

Jen's favorite language is Python.

Sarah's favorite language is C.

Phil's favorite language is Python.

Edward's favorite language is Ruby.

 

 

 

 

 

 

 

 

即便字典存儲的是上千乃至上百萬人的調查結果,這種迴圈也管用。

6.3.2 遍歷字典中的所有鍵

在不需要使用字典中的值時,方法keys() 很有用。下面來遍歷字典favorite_languages ,並將每個被調查者的名字都列印出來:

 

  favorite_languages = {

      'jen': 'python',

      'sarah': 'c',

      'edward': 'ruby',

      'phil': 'python',

      }

 

for name in favorite_languages.keys():

      print(name.title())

 

 

 

 

 

 

 

 

 

處的代碼行讓Python提取字典favorite_languages 中的所有鍵,並依次將它們存儲到變數name 中。輸出列出了每個被調查者的名字:

 

Jen

Sarah

Phil

Edward

 

 

 

 

 

 

 

 

遍歷字典時,會預設遍歷所有的鍵,因此,如果將上述代碼中的for name in favorite_languages.keys(): 替換為for name in favorite_languages: ,輸出將不變。

如果顯式地使用方法keys() 可讓代碼更容易理解,你可以選擇這樣做,但如果你願意,也可省略它。

在這種迴圈中,可使用當前鍵來訪問與之相關聯的值。下面來列印兩條消息,指出兩位元朋友喜歡的語言。我們像前面一樣遍歷字典中的名字,但在名字為指定朋友的名字時,列印一條消息,指出其喜歡的語言:

 

  favorite_languages = {

      'jen': 'python',

      'sarah': 'c',

      'edward': 'ruby',

      'phil': 'python',

      }

 

friends = ['phil', 'sarah']

  for name in favorite_languages.keys():

      print(name.title())

 

     if name in friends:

          print("  Hi " + name.title() +

              ", I see your favorite language is " +

             favorite_languages[name].title() + "!")

 

 

 

 

 

 

 

 

處,我們創建了一個列表,其中包含我們要通過列印消息,指出其喜歡的語言的朋友。在迴圈中,我們列印每個人的名字,並檢查當前的名字是否在列表friends 中(見)。如果在列表中,就列印一句特殊的問候語,其中包含這位元朋友喜歡的語言。為訪問喜歡的語言,我們使用了字典名,並將變數name 的當前值作為鍵(見)。每個人的名字都會被列印,但只對朋友列印特殊消息:

 

Edward

Phil

  Hi Phil, I see your favorite language is Python!

Sarah

  Hi Sarah, I see your favorite language is C!

Jen

 

 

 

 

 

 

 

 

你還可以使用keys() 確定某個人是否接受了調查。下面的代碼確定Erin是否接受了調查:

 

  favorite_languages = {

      'jen': 'python',

      'sarah': 'c',

      'edward': 'ruby',

      'phil': 'python',

      }

 

if 'erin' not in favorite_languages.keys():

      print("Erin, please take our poll!")

 

 

 

 

 

 

 

 

方法keys() 並非只能用於遍歷;實際上,它返回一個清單,其中包含字典中的所有鍵,因此處的代碼行只是核實'erin' 是否包含在這個列表中。由於她並不包含在這個列表中,因此列印一條消息,邀請她參加調查:

 

Erin, please take our poll!

 

 

 

 

 

 

 

 

6.3.3 按順序遍歷字典中的所有鍵

字典總是明確地記錄鍵和值之間的關聯關係,但獲取字典的元素時,獲取順序是不可預測的。這不是問題,因為通常你想要的只是獲取與鍵相關聯的正確的值。

要以特定的順序返回元素,一種辦法是在for 迴圈中對返回的鍵進行排序。為此,可使用函數sorted() 來獲得按特定順序排列的鍵清單的副本:

 

favorite_languages = {

    'jen': 'python',

    'sarah': 'c',

    'edward': 'ruby',

    'phil': 'python',

    }

 

for name in sorted(favorite_languages.keys()):

    print(name.title() + ", thank you for taking the poll.")

 

 

 

 

 

 

 

 

這條for 語句類似於其他for 語句,但對方法dictionary.keys() 的結果調用了函數sorted() 。這讓Python列出字典中的所有鍵,並在遍歷前對這個列表進行排序。輸出表明,按順序顯示了所有被調查者的名字:

 

Edward, thank you for taking the poll.

Jen, thank you for taking the poll.

Phil, thank you for taking the poll.

Sarah, thank you for taking the poll.

 

 

 

 

 

 

 

 

6.3.4 遍歷字典中的所有值

如果你感興趣的主要是字典包含的值,可使用方法values() ,它返回一個值列表,而不包含任何鍵。例如,如果我們想獲得一個這樣的列表,即其中只包含被調查者選擇的各種語言,而不包含被調查者的名字,可以這樣做:

 

favorite_languages = {

    'jen': 'python',

    'sarah': 'c',

    'edward': 'ruby',

    'phil': 'python',

    }

 

print("The following languages have been mentioned:")

for language in favorite_languages.values():

    print(language.title())

 

 

 

 

 

 

 

 

這條for 語句提取字典中的每個值,並將它們依次存儲到變數language 中。通過列印這些值,就獲得了一個列表,其中包含被調查者選擇的各種語言:

 

The following languages have been mentioned:

Python

C

Python

Ruby

 

 

 

 

 

 

 

 

這種做法提取字典中所有的值,而沒有考慮是否重複。涉及的值很少時,這也許不是問題,但如果被調查者很多,最終的列表可能包含大量的重複項。為剔除重複項,可使用集合(set)。集合 類似於清單,但每個元素都必須是獨一無二的:

 

  favorite_languages = {

      'jen': 'python',

      'sarah': 'c',

      'edward': 'ruby',

      'phil': 'python',

      }

 

  print("The following languages have been mentioned:")

for language in set(favorite_languages.values()):

      print(language.title())

 

 

 

 

 

 

 

 

通過對包含重複元素的清單調用set() ,可讓Python找出清單中獨一無二的元素,並使用這些元素來創建一個集合。在處,我們使用了set() 來提取favorite_languages.values() 中不同的語言。

結果是一個不重複的列表,其中列出了被調查者提及的所有語言:

 

The following languages have been mentioned:

Python

C

Ruby

 

 

 

 

 

 

 

 

隨著你更深入地學習Python,經常會發現它內置的功能可説明你以希望的方式處理資料。

動手試一試

6-4 詞彙表2 :既然你知道了如何遍歷字典,現在請整理你為完成練習6-3而編寫的代碼,將其中的一系列print 語句替換為一個遍歷字典中的鍵和值的迴圈。確定該迴圈正確無誤後,再在詞彙表中添加5Python術語。當你再次運行這個程式時,這些新術語及其含義將自動包含在輸出中。

glossary = {

    'string': 'A series of characters.',

    'comment': 'A note in a program that the Python interpreter ignores.',

    'list': 'A collection of items in a particular order.',

    'loop': 'Work through a collection of items, one at a time.',

    'dictionary': "A collection of key-value pairs.",

    'key': 'The first item in a key-value pair in a dictionary.',

    'value': 'An item associated with a key in a dictionary.',

    'conditional test': 'A comparison between two values.',

    'float': 'A numerical value with a decimal component.',

    'boolean expression': 'An expression that evaluates to True or False.',

    }

 

for word, definition in glossary.items():

    print("\n" + word.title() + ": " + definition)

 

 

輸出:

 

Dictionary: A collection of key-value pairs.

 

String: A series of characters.

 

Boolean Expression: An expression that evaluates to True or False.

 

Comment: A note in a program that the Python interpreter ignores.

 

Value: An item associated with a key in a dictionary.

 

Loop: Work through a collection of items, one at a time.

 

List: A collection of items in a particular order.

 

Conditional Test: A comparison between two values.

 

Key: The first item in a key-value pair in a dictionary.

 

Float: A numerical value with a decimal component.

6-5 河流 :創建一個字典,在其中存儲三條大河流及其流經的國家。其中一個鍵值對可能是'nile': 'egypt' 

·          使用迴圈為每條河流列印一條消息,如“The Nile runs through Egypt.”

·          使用迴圈將該字典中每條河流的名字都列印出來。

·          使用迴圈將該字典包含的每個國家的名字都列印出來。

rivers = {

    'nile': 'egypt',

    'mississippi': 'united states',

    'fraser': 'canada',

    'kuskokwim': 'alaska',

    'yangtze': 'china',

    }

 

for river, country in rivers.items():

    print("The " + river.title() + " flows through " + country.title() + ".")

 

print("\nThe following rivers are included in this data set:")

for river in rivers.keys():

    print("- " + river.title())

 

print("\nThe following countries are included in this data set:")

for country in rivers.values():

    print("- " + country.title())

 

輸出:

 

The Mississippi flows through United States.

The Yangtze flows through China.

The Fraser flows through Canada.

The Nile flows through Egypt.

The Kuskokwim flows through Alaska.

 

The following rivers are included in this data set:

- Mississippi

- Yangtze

- Fraser

- Nile

- Kuskokwim

 

The following countries are included in this data set:

- United States

- China

- Canada

- Egypt

- Alaska

 

注意:有些人將阿拉斯加視為美國的一個附屬國。

6-6 調查 :在6.3.1節編寫的程式favorite_languages.py中執行以下操作。

·          創建一個應該會接受調查的人員名單,其中有些人已包含在字典中,而其他人未包含在字典中。

·          遍歷這個人員名單,對於已參與調查的人,列印一條消息表示感謝。對於還未參與調查的人,列印一條消息邀請他參與調查。

favorite_languages = {

    'jen': 'python',

    'sarah': 'c',

    'edward': 'ruby',

    'phil': 'python',

    }

 

for name, language in favorite_languages.items():

    print(name.title() + "'s favorite language is " +

        language.title() + ".")

 

print("\n")

 

coders = ['phil', 'josh', 'david', 'becca', 'sarah', 'matt', 'danielle']

for coder in coders:

    if coder in favorite_languages.keys():

        print("Thank you for taking the poll, " + coder.title() + "!")

    else:

        print(coder.title() + ", what's your favorite programming language?")

 

 

輸出:

 

Jen's favorite language is Python.

Sarah's favorite language is C.

Phil's favorite language is Python.

Edward's favorite language is Ruby.

 

 

Thank you for taking the poll, Phil!

Josh, what's your favorite programming language?

David, what's your favorite programming language?

Becca, what's your favorite programming language?

Thank you for taking the poll, Sarah!

Matt, what's your favorite programming language?

Danielle, what's your favorite programming language?

6.4 嵌套

有時候,需要將一系列字典存儲在清單中,或將清單作為值存儲在字典中,這稱為嵌套 。你可以在清單中嵌套字典、在字典中嵌套清單甚至在字典中嵌套字典。正如下面的示例將演示的,嵌套是一項強大的功能。

6.4.1 字典清單

字典alien_0 包含一個外星人的各種資訊,但無法存儲第二個外星人的資訊,更別說螢幕上全部外星人的資訊了。如何管理成群結隊的外星人呢?一種辦法是創建一個外星人列表,其中每個外星人都是一個字典,包含有關該外星人的各種資訊。例如,下面的代碼創建一個包含三個外星人的列表:

aliens.py

 

  alien_0 = {'color': 'green', 'points': 5}

  alien_1 = {'color': 'yellow', 'points': 10}

  alien_2 = {'color': 'red', 'points': 15}

 

aliens = [alien_0, alien_1, alien_2]

 

  for alien in aliens:

      print(alien)

 

 

 

 

 

 

 

 

我們首先創建了三個字典,其中每個字典都表示一個外星人。在處,我們將這些字典都放到一個名為aliens 的列表中。最後,我們遍歷這個列表,並將每個外星人都列印出來:

 

{'color': 'green', 'points': 5}

{'color': 'yellow', 'points': 10}

{'color': 'red', 'points': 15}

 

 

 

 

 

 

 

 

更符合現實的情形是,外星人不止三個,且每個外星人都是使用代碼自動生成的。在下面的示例中,我們使用range() 生成了30個外星人:

 

  # 創建一個用於存儲外星人的空清單

  aliens = []

 

  # 創建30個綠色的外星人

for alien_number in range(30):

     new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}

     aliens.append(new_alien)

 

  # 顯示前五個外星人

for alien in aliens[:5]:

      print(alien)

  print("...")

 

  # 顯示創建了多少個外星人

print("Total number of aliens: " + str(len(aliens)))

 

 

 

 

 

 

 

 

在這個示例中,首先創建了一個空清單,用於存儲接下來將創建的所有外星人。在處,range() 返回一系列數字,其唯一的用途是告訴Python我們要重複這個迴圈多少次。每次執行這個迴圈時,都創建一個外星人(見),並將其附加到列表aliens 末尾(見)。在處,使用一個切片來列印前五個外星人;在處,列印列表的長度,以證明確實創建了30個外星人:

 

{'speed': 'slow', 'color': 'green', 'points': 5}

{'speed': 'slow', 'color': 'green', 'points': 5}

{'speed': 'slow', 'color': 'green', 'points': 5}

{'speed': 'slow', 'color': 'green', 'points': 5}

{'speed': 'slow', 'color': 'green', 'points': 5}

...

 

Total number of aliens: 30

 

 

 

 

 

 

 

 

這些外星人都具有相同的特徵,但在Python看來,每個外星人都是獨立的,這讓我們能夠獨立地修改每個外星人。

在什麼情況下需要處理成群結隊的外星人呢?想像一下,可能隨著遊戲的進行,有些外星人會變色且移動速度會加快。必要時,我們可以使用for 迴圈和if 語句來修改某些外星人的顏色。例如,要將前三個外星人修改為黃色的、速度為中等且值10個點,可以這樣做:

 

# 創建一個用於存儲外星人的空清單

aliens = []

 

# 創建30個綠色的外星人

for alien_number in range (0,30):

    new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}

    aliens.append(new_alien)

 

for alien in aliens[0:3]:

    if alien['color'] == 'green':

        alien['color'] = 'yellow'

        alien['speed'] = 'medium'

        alien['points'] = 10

 

# 顯示前五個外星人

for alien in aliens[0:5]:

    print(alien)

print("...")

 

 

 

 

 

 

 

 

鑒於我們要修改前三個外星人,需要遍歷一個隻包含這些外星人的切片。當前,所有外星人都是綠色的,但情況並非總是如此,因此我們編寫了一條if 語句來確保只修改綠色外星人。如果外星人是綠色的,我們就將其顏色改為'yellow' ,將其速度改為'medium' ,並將其點數改為10 ,如下面的輸出所示:

 

{'speed': 'medium', 'color': 'yellow', 'points': 10}

{'speed': 'medium', 'color': 'yellow', 'points': 10}

{'speed': 'medium', 'color': 'yellow', 'points': 10}

{'speed': 'slow', 'color': 'green', 'points': 5}

{'speed': 'slow', 'color': 'green', 'points': 5}

...

 

 

 

 

 

 

 

 

你可以進一步擴展這個迴圈,在其中添加一個elif 代碼塊,將黃色外星人改為移動速度快且值15個點的紅色外星人,如下所示(這裡只列出了迴圈,而沒有列出整個程式):

 

for alien in aliens[0:3]:

    if alien['color'] == 'green':

        alien['color'] = 'yellow'

        alien['speed'] = 'medium'

        alien['points'] = 10

    elif alien['color'] == 'yellow':

        alien['color'] = 'red'

        alien['speed'] = 'fast'

        alien['points'] = 15

 

 

 

 

 

 

 

 

經常需要在清單中包含大量的字典,而其中每個字典都包含特定物件的眾多資訊。例如,你可能需要為網站的每個使用者創建一個字典(就像6.3.1節的user.py中那樣),並將這些字典存儲在一個名為users 的列表中。在這個清單中,所有字典的結構都相同,因此你可以遍歷這個列表,並以相同的方式處理其中的每個字典。

6.4.2 在字典中存儲清單

有時候,需要將清單存儲在字典中,而不是將字典存儲在清單中。例如,你如何描述顧客點的比薩呢?如果使用清單,只能存儲要添加的比薩配料;但如果使用字典,就不僅可在其中包含配料列表,還可包含其他有關比薩的描述。

在下面的示例中,存儲了比薩的兩方面資訊:外皮類型和配料列表。其中的配料列表是一個與鍵'toppings' 相關聯的值。要訪問該清單,我們使用字典名和鍵'toppings' ,就像訪問字典中的其他值一樣。這將返回一個配料列表,而不是單個值:

pizza.py

 

  # 存儲所點比薩的資訊

pizza = {

      'crust': 'thick',

      'toppings': ['mushrooms', 'extra cheese'],

      }

 

  # 概述所點的比薩

print("You ordered a " + pizza['crust'] + "-crust pizza " +

      "with the following toppings:")

 

for topping in pizza['toppings']:

      print("\t" + topping)

 

 

 

 

 

 

 

 

我們首先創建了一個字典,其中存儲了有關顧客所點比薩的資訊(見)。在這個字典中,一個鍵是'crust' ,與之相關聯的值是字串'thick' ;下一個鍵是'toppings' ,與之相關聯的值是一個清單,其中存儲了顧客要求添加的所有配料。製作前我們概述了顧客所點的比薩(見)。為列印配料,我們編寫了一個for 迴圈(見)。為訪問配料列表,我們使用了鍵'toppings' ,這樣Python將從字典中提取配料清單。

下面的輸出概述了要製作的比薩:

 

You ordered a thick-crust pizza with the following toppings:

    mushrooms

    extra cheese

 

 

 

 

 

 

 

 

每當需要在字典中將一個鍵關聯到多個值時,都可以在字典中嵌套一個清單。在本章前面有關喜歡的程式設計語言的示例中,如果將每個人的回答都存儲在一個清單中,被調查者就可選擇多種喜歡的語言。在這種情況下,當我們遍歷字典時,與每個被調查者相關聯的都是一個語言清單,而不是一種語言;因此,在遍歷該字典的for 迴圈中,我們需要再使用一個for 迴圈來遍歷與被調查者相關聯的語言清單:

favorite_languages.py

 

favorite_languages = {

      'jen': ['python', 'ruby'],

      'sarah': ['c'],

      'edward': ['ruby', 'go'],

      'phil': ['python', 'haskell'],

      }

 

for name, languages in favorite_languages.items():

      print("\n" + name.title() + "'s favorite languages are:")

     for language in languages:

          print("\t" + language.title())

 

 

 

 

 

 

 

 

正如你看到的,現在與每個名字相關聯的值都是一個列表(見)。請注意,有些人喜歡的語言只有一種,而有些人有多種。遍歷字典時(見),我們使用了變數languages 來依次存儲字典中的每個值,因為我們知道這些值都是列表。在遍歷字典的主迴圈中,我們又使用了一個for 迴圈來遍歷每個人喜歡的語言清單(見)。現在,每個人想列出多少種喜歡的語言都可以:

 

Jen's favorite languages are:

    Python

    Ruby

 

Sarah's favorite languages are:

    C

 

Phil's favorite languages are:

    Python

    Haskell

 

Edward's favorite languages are:

    Ruby

    Go

 

 

 

 

 

 

 

 

為進一步改進這個程式,可在遍歷字典的for 迴圈開頭添加一條if 語句,通過查看len(languages) 的值來確定當前的被調查者喜歡的語言是否有多種。如果他喜歡的語言有多種,就像以前一樣顯示輸出;如果只有一種,就相應修改輸出的措辭,如顯示Sarah's favorite language is C 

注意  清單和字典的嵌套層級不應太多。如果嵌套層級比前面的示例多得多,很可能有更簡單的解決問題的方案。

6.4.3 在字典中存儲字典

可在字典中嵌套字典,但這樣做時,代碼可能很快複雜起來。例如,如果有多個網站用戶,每個都有獨特的用戶名,可在字典中將使用者名作為鍵,然後將每位元使用者的資訊存儲在一個字典中,並將該字典作為與用戶名相關聯的值。在下面的程式中,對於每位元使用者,我們都存儲了其三項資訊:名、姓和居住地;為訪問這些資訊,我們遍歷所有的用戶名,並訪問與每個用戶名相關聯的資訊字典:

many_users.py

 

  users = {

      'aeinstein': {

          'first': 'albert',

          'last': 'einstein',

          'location': 'princeton',

          },

 

      'mcurie': {

          'first': 'marie',

          'last': 'curie',

          'location': 'paris',

          },

 

      }

 

for username, user_info in users.items():

     print("\nUsername: " + username)

     full_name = user_info['first'] + " " + user_info['last']

      location = user_info['location']

 

     print("\tFull name: " + full_name.title())

      print("\tLocation: " + location.title())

 

 

 

 

 

 

 

 

我們首先定義了一個名為users 的字典,其中包含兩個鍵:用戶名'aeinstein' 'mcurie' ;與每個鍵相關聯的值都是一個字典,其中包含使用者的名、姓和居住地。在處,我們遍歷字典users ,讓Python依次將每個鍵存儲在變數username 中,並依次將與當前鍵相關聯的字典存儲在變數user_info 中。在主迴圈內部的處,我們將用戶名列印出來。

處,我們開始訪問內部的字典。變數user_info 包含使用者資訊字典,而該字典包含三個鍵:'first' 'last' 'location' ;對於每位用戶,我們都使用這些鍵來生成整潔的姓名和居住地,然後列印有關使用者的簡要資訊(見

 

Username: aeinstein

    Full name: Albert Einstein

    Location: Princeton

 

Username: mcurie

    Full name: Marie Curie

    Location: Paris

 

 

 

 

 

 

 

 

請注意,表示每位元使用者的字典的結構都相同,雖然Python並沒有這樣的要求,但這使得嵌套的字典處理起來更容易。倘若表示每位元使用者的字典都包含不同的鍵,for 迴圈內部的代碼將更複雜。

動手試一試

6-7  :在為完成練習6-1而編寫的程式中,再創建兩個表示人的字典,然後將這三個字典都存儲在一個名為people 的列表中。遍歷這個清單,將其中每個人的所有資訊都列印出來。

# 創建一個用於存儲人的空清單。

people = []

 

# 定義一些人並將他們添加到前述列表中。

person = {

    'first_name': 'eric',

    'last_name': 'matthes',

    'age': 43,

    'city': 'sitka',

    }

people.append(person)

 

person = {

    'first_name': 'ever',

    'last_name': 'matthes',

    'age': 5,

    'city': 'sitka',

    }

people.append(person)

 

person = {

    'first_name': 'willie',

    'last_name': 'matthes',

    'age': 8,

    'city': 'sitka',

    }

people.append(person)

 

# 顯示清單包含的每個字典中的資訊。

for person in people:

    name = person['first_name'].title() + " " + person['last_name'].title()

    age = str(person['age'])

    city = person['city'].title()

   

    print(name + ", of " + city + ", is " + age + " years old.")

 

輸出:

 

Eric Matthes, of Sitka, is 43 years old.

Ever Matthes, of Sitka, is 5 years old.

Willie Matthes, of Sitka, is 8 years old.

6-8 寵物 :創建多個字典,對於每個字典,都使用一個寵物的名稱來給它命名;在每個字典中,包含寵物的類型及其主人的名字。將這些字典存儲在一個名為pets 的列表中,再遍歷該列表,並將寵物的所有資訊都列印出來。

# 創建一個用於存儲寵物的空清單。

pets = []

 

# 定義各個寵物並將其存儲到清單中。

pet = {

    'animal type': 'python',

    'name': 'john',

    'owner': 'guido',

    'weight': 43,

    'eats': 'bugs',

}

pets.append(pet)

 

pet = {

    'animal type': 'chicken',

    'name': 'clarence',

    'owner': 'tiffany',

    'weight': 2,

    'eats': 'seeds',

}

pets.append(pet)

 

pet = {

    'animal type': 'dog',

    'name': 'peso',

    'owner': 'eric',

    'weight': 37,

    'eats': 'shoes',

}

pets.append(pet)

 

# 顯示每個寵物的資訊。

for pet in pets:

    print("\nHere's what I know about " + pet['name'].title() + ":")

    for key, value in pet.items():

        print("\t" + key + ": " + str(value))

 

 

輸出:

 

Here's what I know about John:

    weight: 43

    animal type: python

    name: john

    owner: guido

    eats: bugs

 

Here's what I know about Clarence:

    weight: 2

    animal type: chicken

    name: clarence

    owner: tiffany

    eats: seeds

 

Here's what I know about Peso:

    weight: 37

    animal type: dog

    name: peso

    owner: eric

    eats: shoes

6-9 喜歡的地方 :創建一個名為favorite_places 的字典。在這個字典中,將三個人的名字用作鍵;對於其中的每個人,都存儲他喜歡的1~3個地方。為讓這個練習更有趣些,可讓一些朋友指出他們喜歡的幾個地方。遍歷這個字典,並將其中每個人的名字及其喜歡的地方列印出來。

favorite_places = {

    'eric': ['bear mountain', 'death valley', 'tierra del fuego'],

    'erin': ['hawaii', 'iceland'],

    'ever': ['mt. verstovia', 'the playground', 'south carolina']

    }

 

for name, places in favorite_places.items():

    print("\n" + name.title() + " likes the following places:")

    for place in places:

        print("- " + place.title())

 

 

輸出:

 

Ever likes the following places:

- Mt. Verstovia

- The Playground

- South Carolina

 

Erin likes the following places:

- Hawaii

- Iceland

 

Eric likes the following places:

- Bear Mountain

- Death Valley

- Tierra Del Fuego

6-10 喜歡的數位 :修改為完成練習6-2而編寫的程式,讓每個人都可以有多個喜歡的數位,然後將每個人的名字及其喜歡的數字列印出來。

favorite_numbers = {

    'mandy': [42, 17],

    'micah': [42, 39, 56],

    'gus': [7, 12],

    }
 
for name, numbers in favorite_numbers.items():
    print("\n" + name.title() + " likes the following numbers:")
    for number in numbers:
        print("  " + str(number))

 

 

輸出:

 

Micah likes the following numbers:
  42
  39
  56
 
Mandy likes the following numbers:
  42
  17
 
Gus likes the following numbers:
  7
  12

6-11 城市 :創建一個名為cities 的字典,其中將三個城市名用作鍵;對於每座城市,都創建一個字典,並在其中包含該城市所屬的國家、人口約數以及一個有關該城市的事實。在表示每座城市的字典中,應包含country population fact 等鍵。將每座城市的名字以及有關它們的資訊都列印出來。

cities = {
    'santiago': {
        'country': 'chile',
        'population': 6158080,
        'nearby mountains': 'andes',
        },
    'talkeetna': {
        'country': 'alaska',
        'population': 876,
        'nearby mountains': 'alaska range',
        },
    'kathmandu': {
        'country': 'nepal',
        'population': 1003285,
        'nearby mountains': 'himilaya',
        }
    }
 
for city, city_info in cities.items():
    country = city_info['country'].title()
    population = city_info['population']
    mountains = city_info['nearby mountains'].title()
 
    print("\n" + city.title() + " is in " + country + ".")
    print("  It has a population of about " + str(population) + ".")
    print("  The " + mountains + " mountains are nearby.")

 

 

輸出:

 

Santiago is in Chile.
  It has a population of about 6158080.
  The Andes mountains are nearby.
 
Kathmandu is in Nepal.
  It has a population of about 1003285.
  The Himilaya mountains are nearby.
 
Talkeetna is in Alaska.
  It has a population of about 876.
  The Alaska Range mountains are nearby.

6-12 擴展 :本章的示例足夠複雜,可以以很多方式進行擴展了。請對本章的一個示例進行擴展:添加鍵和值、調整程式要解決的問題或改進輸出的格式。

6.5 小結

在本章中,你學習了:如何定義字典,以及如何使用存儲在字典中的資訊;如何訪問和修改字典中的元素,以及如何遍歷字典中的所有資訊;如何遍歷字典中所有的鍵-值對、所有的鍵和所有的值;如何在清單中嵌套字典、在字典中嵌套清單以及在字典中嵌套字典。

在下一章中,你將學習while 迴圈以及如何從用戶那裡獲取輸入。這是激動人心的一章,讓你知道如何將程式變成交互性的——能夠對用戶輸入作出回應。

0 留言:

發佈留言