Python從菜鳥到高手(16):創建和使用字典

字典可以用下面的方式創建。

phoneBook = {"Bill":"1234", "Mike":"4321", "John":"6645","Mary":"7753"}

我們可以看到,一個字典是用一對大括號來創建的,鍵與值之間用冒號(:)分隔,每一對鍵值之間用逗號(,)分隔。如果大括號中沒有任何的值,就是一個空的字典。

在字典中,鍵是唯一的,這樣才能通過鍵唯一定位某一個值。當然,如果鍵不唯一,那麼程序也不會拋出異常,只是相同的鍵值會被覆蓋。

phoneBook = {"Bill":"1234", "Bill":"4321", "John":"6645","Mary":"7753"}

我們可以看到上面的這行代碼定義的字典中,前兩對鍵值中的鍵是相同的,如果通過Bill定位,那麼查到的值是"4321",而不是"1234"。

1. dict函數

可以用dict函數,通過其他映射(如其他的字典)或鍵值對的序列建立字典。

items = [["Bill","1234"], ("Mike","4321"),["Mary", "7753"]]
d = dict(items)
# 運行結果:{'Bill': '1234', 'Mike': '4321', 'Mary': '7753'}
print(d)

我上面的代碼可以看出,爲dict函數傳入了一個列表類型參數值,列表的每一個元素或者是一個列表,或者是一個元組。每一個元素值包含兩個值。第1個值表示鍵,第2個值表示值。這樣dict函數就會將每一個items列表元素轉換爲字典中對應的一個鍵值。

dict函數還可以通過關鍵字參數來創建字典。

items = dict(name = "Bill", number = "5678", age = 45)
# 運行結果:{'name': 'Bill', 'number': '5678', 'age': 45}
print(items)

dict函數如果不指定任何參數,那麼該函數會返回一個空的字典。

本例通過控制檯輸入一組key和value,首先通過每一對key-value創建一個列表,並將這個列表放到一個大的列表(items)中。最後使用dict函數將items轉換爲字典,並在控制檯輸出這個字典。

items = []                          # 定義一個空的列表
while True:
    key = input("請輸入Key:")      # 從控制檯輸入一個key
    if key == "end":                # 當key值爲"end"時退出循環
        break;
    value = input("請輸入value:")  # 從控制檯輸入一個value
    keyValue = [key, value]         # 用key和value創建一個列表
    items.append(keyValue)          # 將key-value組成的列表添加到items中

d = dict(items)                 # 使用dict函數將items轉換爲字典
print(d)                            # 在控制檯輸出字典

程序運行結果如下圖所示。

image.png

2. 字典的基本操作

字典的很多操作與列表類似,如下面的一些操作仍然適合於字典。

• len(dict):返回字典dict中元素(鍵值對)的數量。

• dict[key]:返回關聯到鍵key上的值,對於列表,key就是索引。

• dict[key] = value:將值value關聯到鍵key上。

• del dict[key]:刪除鍵爲key的項。

• key in dict:檢查dict中是否包含有鍵爲key的項。

儘管字典和列表有很多特性相同,但也有下面的一些重要區別。

• 鍵類型:字典的鍵可以是任意不可變類型,如浮點數、元組、字符串等,而列表的key只能是整數類型。

• 自動添加:字典可以通過鍵值自動添加新的項,也就是說,進行dict[key] = value操作時,如果key在字典dict中不存在,那麼就會在dict中添加一個新的元素(鍵-值對)。而在列表中,必須要使用append方法或insert方法才能在列表中添加新的元素。

• 查找成員:在字典中使用key in dict操作,查找的是key,而不是value。在列表中使用key in dict操作,查找的是值,而不是索引。對於列表來說,key就代表值。儘管字典和列表在引用其中的值時都是用dict[key],但key in dict操作的含義是不同的。

注意:由於字典中的元素是通過一定的數據結構(排序樹或其他數據結構)存儲的,所以在字典中查找key要比在字典中查找值更高效,數據量越大,這種效果越明顯。

本例演示了字典的鍵類型,爲字典添加新的元素(鍵值對),以及如何使用in操作符在字典中查找指定的key。在演示in操作符時,在名爲IDEs的字典中添加各種IDE支持的編程語言以及所屬機構,然後通過控制檯輸入要查找的IDE名稱,並指定要查找IDE支持的編程語言或所屬機構,最後在控制檯輸出結果。

dict = {}                                       # 定義一個字典
dict[20] = "Bill"                               # 向字典dict中添加整數類型的key
dict["Mike"] = {'age':30,'salary':3000}         # 向字典dict中添加字符串類型的key
dict[(12, "Mike", True)] = "hello"              # 向字典dict中添加元組類型的key
print(dict)                                 # 輸出字典dict中的所有元素

#list = []                                      # 定義一個列表
#list[30] = "hello"                             # 索引爲30的元素並不存在,所以會拋出異常

IDEs = {                                        # 定義一個字典
    'eclipse':
        {
        'languages':['Java', 'Python', 'JavaScript','PHP'],
        'organization':'Eclipse基金會'
        },
    'visualstudio':
        {
        'languages':['C#','C++', 'VB.NET'],
        'organization':'微軟'
        },
    'webstorm':
        {
        'languages':['JavaScript'],
        'organization':'JetBrains'
        }

    }

labels = {                                  #  定義一個字典,用於存儲顯示的標籤
    'languages':'支持的編程語言',
    'organization':'所屬機構'
    }
IDE = input('請輸入IDE的名字:')               # 從控制檯輸入一個IDE的名字
findIDE = IDE.replace(" ", "").lower()      # 去除IDE名字中的所有空格,並將其轉換爲小寫
# 從控制檯輸入lang或org,表示要查詢IDE支持的編程語言或所屬機構
choice = input('要查詢IDE支持的編程語言(lang)還是所屬組織機構(org)?')
if choice == "lang": key = 'languages'
if choice == "org": key = 'organization'

#  在IDEs字典中查找指定的IDE,如果找到,就輸出查詢結果。
if findIDE in IDEs:
    print("{}{}是{}.".format(IDE, labels[key], IDEs[findIDE][key]))

程序運行結果如下圖所示。

image.png

在上面的代碼中,從字典IDEs中查找指定IDE時,首先將輸入的IDE名字中所有的空格去掉,然後又將其中所有的字母都轉換爲小寫。而IDEs中保存的key也符合這個規則,也就是IDE名字全部用小寫,而且中間沒有空格。由於在輸入IDE名字時,可能會輸入多個空格,名字也可能帶有大小寫字母,所以將輸入的IDE名字轉換爲IDEs中key的命名規則,以保證輸入不同格式的IDE名字都可以查到相應的IDE。例如,輸入“Visual Studio”、“visual studio”、“VisualStudio”都可以查詢到Visual Studio的相應信息。

3. 字典的格式化字符串

在前面的文章講過使用百分號(%)配合元組對字符串進行格式化的方式。在字符串中使用%s、%d等格式表示要替換的值,這個字符串可以稱爲模板,然後用字符串模板與元組通過%進行格式化。

'xyz %d  abc %s' % (20,'ok')

如果使用字典對字符串進行格式化,要比使用元組更酷。因爲在字符串模板中可以用命名的方式指定格式化參數。在Python2.x中,仍然可以使用%運算符和字典對字符串進行格式化,不過在Python3.x中,改用了字符串的format_map方法,而且格式化參數需要用一對花括號({})括起來,格式化字符串的具體使用方式見例6.3。

本例演示瞭如何使用字符串的format_map方法和字典對字符串進行格式化,並與使用元組和%對字符串進行格式化的方式進行對比。

values1 = (1,3,"hello")                     #  定義一個格式化參數元組zheyangzuo
str1 = "abc %d,  xyz %d,  %s world"             #  定義一個字符串模板
print(str1 % values1)                       #  使用%和元組格式化字符串

# 定義一個格式化參數字典
values2 = {'title':'極客起源', 'url':'https://geekori.com', 'company':'歐瑞科技'}

#  定義一個字符串模板
str2 = """
<html>
    <head>
        <title>{title}</title>
        <meta charset="utf-8" /> 
    <head>
    <body>
        <h1>{title}</h1>
        <a href="{url}">{company}</a>
    </body>
</html>
"""
print(str2.format_map(values2))         #  使用format_map方法格式化字符串

程序運行結果如下圖所示。

image.png

我們可以看到,format_map方法使用的字符串模板中,格式化參數使用一對花括號({})表示,花括號裏面就是格式化參數的名字,如“{title}”,這個格式化參數名也是字典中的key。使用字典提供格式化參數值的好處是不需要按字符串模板中的順序指定格式化參數值,而且同一個格式化參數可以放在多個位置,在格式化時會替換所有同名的格式化參數。如本例中的{title}放在了兩個位置。如果格式化模板中的格式化參數名在字典中未找到,系統會拋出異常。

image

4. 序列與迭代

之所以在這裏講序列如何在迭代中使用,是因爲到現在爲止,我們已經講了三種序列:列表、元組和字典。通過不同的迭代方式,可以非常方便地對序列進行迭代。本節會爲讀者詳細介紹Python語言中提供的各種序列迭代方式。

(1)獲取字典中key的列表

在使用字典時,如果要想知道字典裏有哪些key,可以直接使用for語句對字典進行遍歷。

dict = {'x':1, 'y':2,'z':3}
#  輸出x y z
for key in dict:
    print(key, end=' ')

上面的代碼中,key的值分別爲x、y、z,因此,會輸出“x y z”。

(2)同時獲取字典中的key和value列表

如果要同時獲取字典中的key和value,除了在上面的代碼中使用dict[key]獲取值外,還可以使用字典中的items方法同時獲取key和value。

dict = {'x':1, 'y':2,'z':3}
#  同時獲取字典中的key和value
#  運行結果:x 1 y 2 z 3
for key,value in dict.items():
    print(key, value, end=' ')

(3)並行迭代

如果想同時迭代兩個或多個序列,那麼可以使用range函數獲取序列索引的範圍,然後使用for語句進行迭代。對多個序列進行迭代,一般要求序列中元素個數相同。

names = ["Bill", "Mary", "John"]
ages = [30,40,20]
# 運行結果:Bill 30 Mary 40 John 20
for i in range(len(names)):
    print(names[i],ages[i], end=" ")

(4)壓縮序列

這裏的壓縮序列是指使用zip函數將兩個或多個序列的對應元素作爲一個元組放到一起,進行壓縮的兩個或多個序列的元素個數如果不相同,以元素個數最少的爲準。例如,下面的2個序列如果用zip函數進行壓縮,會得到一個長度爲2的新序列,每一個序列元素是一個元組。

companies = ["歐瑞科技", "Google", "Facebook"]
websites = ["https://geekori.com", "https://www.googel.com"]
# 運行結果:('歐瑞科技', 'https://geekori.com') ('Google', 'https://www.googel.com')
for value in zip(companies, websites):
    print(value, end =" ")

在上面的代碼中,companies列表中有3個元素,而websites列表中只有兩個元素, zip函數會以元素少的列表爲準,因此最後的結果是以websites列表爲準,得到的壓縮後的列表元素只有2個元素。由於zip函數返回的序列形式比較複雜,所以不能直接使用print函數輸出。

(5)反轉序列迭代

通過reversed函數可以將一個序列反轉,代碼如下:

companies = reversed(["歐瑞科技", "Google", "Facebook"])
# 運行結果:Facebook Google 歐瑞科技
for value in companies:
    print(value, end =" ")

《Python從菜鳥到高手》已經出版,開始連載了,購買送視頻課程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章