1. 程式人生 > >【005】Python全棧日記-字典巢狀

【005】Python全棧日記-字典巢狀

在這裡插入圖片描述
本章內容大部分選自《python從入門到實踐》,上課老師只是用幾個例子帶過,沒這麼詳細。

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

1、字典列表
字典alien_0 包含一個外星人的各種資訊,但無法儲存第二個外星人的資訊,更別說螢幕上全部外星人的資訊了。如何管理成群結隊的外星人呢? 一種辦法是建立一個外星人列表,其中每個外星人都是一個字典,包含有關該外星人的各種資訊。例如,下面的程式碼建立一個包含三個外星人的列表:
在這裡插入圖片描述
我們首先建立了三個字典,其中每個字典都表示一個外星人。在❶處,我們將這些字典都放到一個名為aliens 的列表中。最後,我們遍歷這個列表,並將每個外星人都打印出來:
在這裡插入圖片描述


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

在這個示例中,首先建立了一個空列表,用於儲存接下來將建立的所有外星人。在❶處,range() 返回一系列數字,其唯一的用途是告訴Python我們要重複這個迴圈多少次。每次執行這個迴圈時,都建立一個外星人(見❷),並將其附加到列表aliens 末尾(見❸)。在❹處,使用一個切片來列印前五個外星人;在❺處,列印列表的長度,以證明確
實建立30個外星人:
在這裡插入圖片描述
這些外星人都具有相同的特徵,但在Python看來,每個外星人都是獨立的,這讓我們能夠獨立地修改每個外星人。
在這裡插入圖片描述
在什麼情況下需要處理成群結隊的外星人呢? 想象一下,可能隨著遊戲的進行,有些外星人會變色且移動速度會加快。必要時,我們可以使用for 迴圈和if 語句來修改某些外星人的顏色。例如,要將前三個外星人修改為黃色的、 速度為中等且值10個點,可以這樣做:
在這裡插入圖片描述


鑑於我們要修改前三個外星人,需要遍歷一個只包含這些外星人的切片。當前,所有外星人都是綠色的,但情況並非總是如此,因此我們編寫了一條if 語句來確保只修改綠色外星人。如果外星人是綠色的,我們就將其顏色改為’yellow’,將其速度改為’medium’,並將其點數改為10,如下面的輸出所示:
在這裡插入圖片描述
你可以進一步擴充套件這個迴圈,在其中新增一個elif 程式碼塊,將黃色外星人改為移動速度快且值15個點的紅色外星人,如下所示(這裡只列出了迴圈,而沒有列出整個程式):
在這裡插入圖片描述
經常需要在列表中包含大量的字典,而其中每個字典都包含特定物件的眾多資訊。例如,你可能需要為網站的每個使用者建立一個字典(就像6.3.1節的user.py中那樣),並將這些字典儲存在一個名為users 的列表中。在這個列表中,所有字典的結構都相同,因此你可以遍歷這個列表,並以相同的方式處理其中的每個字典。

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

在下面的示例中,儲存了比薩的兩方面資訊:外皮型別和配料列表。其中的配料列表是一個與鍵’toppings’ 相關聯的值。要訪問該列表,我們使用字典名和鍵’toppings’,就像訪問字典中的其他值一樣。這將返回一個配料列表,而不是單個值:
在這裡插入圖片描述
我們首先建立了一個字典,其中儲存了有關顧客所點比薩的資訊(見❶)。在這個字典中,一個鍵是’crust’,與之相關聯的值是字串’thick’ ;下一個鍵是’toppings’,與之相關聯的值是一個列表,其中儲存了顧客要求新增的所有配料。製作前我們概述了顧客所點的比薩(見❷)。為列印配料,我們編寫了一個for 迴圈(見❸)。為訪問配料列表,我們使用了鍵’toppings’,這樣Python將從字典中提取配料列表。
下面的輸出概述了要製作的比薩:
在這裡插入圖片描述
每當需要在字典中將一個鍵關聯到多個值時,都可以在字典中巢狀一個列表。在本章前面有關喜歡的程式語言的示例中,如果將每個人的回答都儲存在一個列表中,被調查者就可選擇多種喜歡的語言。在這種情況下,當我們遍歷字典時,與每個被調查者相關聯的都是一個語言列表,而不是一種語言;因此,在遍歷該字典的for 迴圈中,我們需要再使用一個for 迴圈來遍歷與被調查者相關聯的語言列表:
在這裡插入圖片描述
正如你看到的,現在與每個名字相關聯的值都是一個列表(見❶)。請注意,有些人喜歡的語言只有一種,而有些人有多種。遍歷字典時(見❷),我們使用了變數languages來依次儲存字典中的每個值,因為我們知道這些值都是列表。在遍歷字典的主迴圈中,我們又使用了一個for 迴圈來遍歷每個人喜歡的語言列表(見❸)。現在,每個人想列出
多少種喜歡的語言都可以:
在這裡插入圖片描述
為進一步改進這個程式,可在遍歷字典的for 迴圈開頭新增一條if 語句,通過檢視len(languages) 的值來確定當前的被調查者喜歡的語言是否有多種。如果他喜歡的語言有多種,就像以前一樣顯示輸出;如果只有一種,就相應修改輸出的措辭,如顯示Sarah’s favorite language is C。

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

3、在字典中儲存字典
可在字典中巢狀字典,但這樣做時,程式碼可能很快複雜起來。例如,如果有多個網站使用者,每個都有獨特的使用者名稱,可在字典中將使用者名稱作為鍵,然後將每位使用者的資訊儲存在一個字典中,並將該字典作為與使用者名稱相關聯的值。在下面的程式中,對於每位使用者,我們都儲存了其三項資訊:名、姓和居住地;為訪問這些資訊,我們遍歷所有的使用者名稱,並訪問與每個使用者名稱相關聯的資訊字典:
在這裡插入圖片描述
我們首先定義了一個名為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 迴圈內部的程式碼將更復雜