巢狀嵌套 有時候可能需要把一組字典存放在串列中,有時又需要把串列的項目當成值存在字典內,這些都叫作「巢狀嵌套( nesting )」。 可以把一組字典巢狀嵌套入串列內,也可以把一系列的串列項目巢狀嵌套入字典中,或是在字典中存入字典。
字典串列
建立一個外星異形串列,其中每個項目都是一個外星異形的字典,該字典中又存放外星異形的各種資訊:
1 2 3 4 5 6 7 8 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 串列中,最後再以迴圈遍訪這個串列:
1 2 3 {'color': 'green', 'points': 5} {'color': 'yellow', 'points': 10} {'color': 'red', 'points': 15}
以現實情況來看,外星異形不止三個,有可能是使用程式動生成的,下面使用 range()生成30個外星異形:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 aliens = [] 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)))
先建立一個空串列 aliens,用來存放自動生成的外星異形。 用range() 返回一系列的數字告訴 Python 要迭代重複迴圈幾次。 每次執行這個迴圈時都會生成一個外星異形字典,並將它新增到 aliens 串列的尾端。 使用切片切出串列前5個外星異形,並將其輸出顯示。 最後輸出串列的總長度,證實生成了30個外星異形字典:
1 2 3 4 5 6 7 {'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, 'speed': 'slow'} ... Total number of aliens: 30
在遊戲程式的進行中,我們會希望外星異形會以不同顏色和不同移動速度程現在畫面上, 當需要變更顏色時,我們會用 for 迴圈和 if 陳述句來修改某些外星異形字典中的 ‘color’:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 aliens = [] 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['points' ] = 10 alien['speed' ] = 'medium' for alien in aliens[:5 ]: print (alien) print ("..." )
修改前三個外星異形,可用串列的切片來配合迴圈遍訪。 if 陳述句確保只改顏色是 ‘green’ 的外星異形,將 ‘color’ 是 ‘green’的外星異形修改成其它樣式的外星異形:
1 2 3 4 5 6 {'color': 'yellow', 'points': 10, 'speed': 'medium'} {'color': 'yellow', 'points': 10, 'speed': 'medium'} {'color': 'yellow', 'points': 10, 'speed': 'medium'} {'color': 'green', 'points': 5, 'speed': 'slow'} {'color': 'green', 'points': 5, 'speed': 'slow'} ...
還可以再擴充這個迴圈,在其中加入 elif 程式區塊,把 ‘yellow’ 黃色的外星異形改為 ‘red’ 紅色、 ‘speed’ 速度是 ‘fast’、而得分 ‘points’ 是15。
1 2 3 4 5 6 7 8 9 for alien in aliens[0:3]: if alien['color'] == 'green': alien['color'] = 'yellow' alien['points'] = 10 alien['speed'] = 'medium' elif alien['color'] == 'yellow': alien['color'] = 'red' alien['points'] = 15 alien['speed'] = 'fast'
在串列中存放大量的字典,而每個字典又含有特定物件的多項資訊,這種情況在編寫程式的歷程中很常遇到。
字典中的串列 除了在把字典存放在串列內,有時候也會有需要用到把串列存放到字典內的情況。 以描述顧客點的披薩來說,如果使用串列,就只能存放加點披薩的配料, 但如果使用字典來儲存,就不僅能存放配料的資訊,還可存放其它關於披薩的描述。
1 2 3 4 5 6 7 8 9 10 11 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)
建立一個字典存放關於顧客所點披薩的資訊,其中第二個鍵是 ‘toppings’,關聯的值是個字串存放顧客所點的配料。 披薩製作前輸出了客人要點的披薩描述,然後用 for 迴圈把所點的配料輸出。 若想存取配料串列,這裡用了 ‘toppings’ 當成「鍵」,讓 Python 從字典中擷取配料串列:
1 2 3 You ordered a thick-crust pizza with the following toppings: mushrooms extra cheese
當您想要在字典中以一個鍵關聯到多個值時,可以在字典中巢狀嵌套串列進去。 以先前提到的最愛程式語言的範例,如果把每個人的喜好存放在在一個串列內,就可以選擇多種喜歡的程式語言。 字典以這種情況存放串列,當迴圈遍訪字典時,關聯每個人員的都是一個程式語言的串列,而不是單個程式語言項:
1 2 3 4 5 6 7 8 9 10 11 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 迴圈來遍訪每個人喜歡的程式語言,現在要列出多少種喜歡的程式語言都可以:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Jen's favorite languages are: Python Ruby Sarah's favorite languages are: C Edward's favorite languages are: Ruby Go Phil's favorite languages are: Python Haskell
字典中的字典 可以在字典中再巢狀嵌套另一個字典,但這樣程式碼很快就變得更複雜了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 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 變數內。 先輸出顯示使用者帳號,再來存取字典內部資訊,並存放到各自的變數名稱後輸出顯示:
1 2 3 4 5 6 7 Username: aeinstein Full name: Albert Einstein Location: Princeton Username: mcurie Full name: Marie Curie Location: Paris
每位使用者帳號所關聯的字典內部結構是相同的,雖然 Python 沒有要求一定要相同, 但為了在處理巢狀嵌套字典時較簡單容易,這樣作才是正確的。 假日每位使用者帳號所關聯的字典內部都用不同的「鍵」,那麼 for 迴圈內部要存取每位使用者的資訊時就會變得十分複雜。