1. 程式人生 > >python快速上手_第五章 字典

python快速上手_第五章 字典

字典資料型別

python中的字典,類似於java中的 Map。以鍵值對的形式儲存。

字典的索引不只是整數,可以是不同的資料型別。 字典的索引被稱為’鍵’ 。 鍵和值稱為 ‘鍵-值’對。

字典輸入時是 {}

>>> mycat = {'size':'fat','color':'gray','disposition':'loud'}
>>> mycat
{'size': 'fat', 'color': 'gray', 'disposition': 'loud'}

可以通過鍵來訪問這些值:

>>> mycat['color']
'gray'
>>> 'My cat has '+mycat['color'] + ' fur'
'My cat has gray fur'

字典與列表

列表是排序的, 字典是不排序的。在列表中,表項的順序很重要;在字典中,鍵 - 值對輸入的順序並不重要。

字典是不排序的,所以字典不能像列表那樣切片。

>>> spam = ['a','b','c']
>>> bacon = ['b','c','a']
>>> spam == bacon
False
>>> eggs = {'a':'a1','b':'b1'}
>>> ham = {'b':'b1','a':'a1'}
>>> eggs == ham
True

嘗試訪問不存在的鍵時,會報錯 KeyError

>>> spam = {'name':'mike','age':7}
>>> spam['age']
7
>>> spam['sex']
Traceback (most recent call last):
  File "<pyshell#280>", line 1, in <module>
    spam['sex']
KeyError: 'sex'

字典是不排序的,並可以使用任意值為鍵,這樣可以更好的來組織資料

下面是用字典來儲存朋友的生日的小程式:

birthdays = {'Alice':'Apr 1','Bob':'Dec 12','Mike':'Sep 14'}

while True:
    print('Enter a name: (blank to quit)')
    name = input()

    if name == '':
        break
    if name in birthdays:
        print(birthdays[name] + ' is the birthday of '+name)
    else:
        print('I do not have bithday information for '+name)
        print('What is their birthday?')
        bday = input()
        birthdays[name] = bday
        print('Birthday database updated')
    

keys()、values()和items()方法

這三個方法返回類似列表的值, 分別是 字典的鍵、值 和 鍵 - 值對。

返回的並不是真正的列表,它們不能被修改,沒有 append()方法。但是可用於 for 迴圈。

字典的遍歷,類似於Java中的Map的遍歷, 可以獲取到 key的集合,value的集合,以及 key 和value封裝的實體

迴圈獲取每個值

>>> spam = {'color':'red','age':42}
>>> for v in spam.values():
	print(v)

red
42

迴圈獲取每個鍵

>>> for k in spam.keys():
	print(k)

color
age

獲取鍵值對

>>> for i in spam.items():
	print(i)

('color', 'red')
('age', 42)

這些返回的並不是真正的列表,沒有append方法,會報錯AttributeError:

>>> spam.keys().append('a')
Traceback (most recent call last):
  File "<pyshell#294>", line 1, in <module>
    spam.keys().append('a')
AttributeError: 'dict_keys' object has no attribute 'append'

如果希望得到一個真正的列表,可以通過 list()函式進行轉換。

>>> spam = {'color':'red','age':42}
>>> spam.keys()
dict_keys(['color', 'age'])
>>> newSpamKey = list(spam.keys())
>>> newSpamKey
['color', 'age']
>>> newSpamKey.append('Hello')
>>> newSpamKey
['color', 'age', 'Hello']

字典遍歷之多重賦值

>>> spam
{'color': 'red', 'age': 42}
>>> for k,v in spam.items():
	print('Key : '+k + ' Value : '+str(v))

Key : color Value : red
Key : age Value : 42

檢查字典中是否存在鍵或值

我們之前用 in 和 not in 來檢查某個值是否在列表中。 這兩個操作符同樣可用於字典中, 檢查某個鍵或者值是否在字典中。

>>> spam = {'name':'Alice','age':20}
>>> 'name' in spam.keys()
True
>>> 20 in spam.values()
True
>>> 'name' in spam
True
>>> 'Bob' not in spam.keys()
True

in spam 等同於 in spam.keys().

get()方法

在訪問一個鍵之前,檢查該鍵是否在字典中,這比較麻煩。 可以使用 get()方法, 兩個引數: 要獲取值的鍵,和如果該鍵不存在時,返回的備用值。

>>> picnicItems = {'apples': 5,'cups':2}
>>> 'I am bringing '+ str(picnicItems.get('cups',0)) + ' cups.'
'I am bringing 2 cups.'
>>> 'I am bringing '+ str(picnicItems.get('eggs',0)) + ' eggs.'
'I am bringing 0 eggs.'

因為字典中沒有 key 為 eggs的 value,所以會返回 0 。 如果不使用這種方式, 直接去獲取一個不存在的鍵,會報錯。

setdefault()方法

我們常常會判斷是否在字典裡有某個鍵,如果沒有,則存入一個預設值。例如下面的程式碼:

>>> spam = {'name':'Alice','age':5}
>>> if 'color' not in spam:
	spam['color'] = 'black'

>>> spam
{'name': 'Alice', 'age': 5, 'color': 'black'}

setdefault()方法就很好的解決了這個問題, 傳入兩個引數, 第一個引數,是要檢查的鍵。第二個引數,是如果該鍵不存在時要設定的值。如果該鍵存在,方法就會返回該鍵的值。

>>> spam = {'name':'Alice','age':5}
>>> spam.setdefault('color','red')
'red'
>>> spam
{'name': 'Alice', 'age': 5, 'color': 'red'}
>>> spam.setdefault('color','white')
'red'
>>> spam
{'name': 'Alice', 'age': 5, 'color': 'red'}

可以確保只有一個鍵存在。

下面有一個程式,統計每個字元出現的次數。

message = 'It was a nice day in April, and the clocks were strinking thirteen'

count = {}

for character in message:
    count.setdefault(character,0)
    count[character] = count[character] + 1

print(count)

漂亮列印

需要匯入 pprint 模組。 就可以使用 pprint 函式 和 pformat 函式。它們將‘漂亮的列印’一個字典。

import pprint

message = 'It was a nice day in April, and the clocks were strinking thirteen'

count = {}

for character in message:
    count.setdefault(character,0)
    count[character] = count[character] + 1

pprint.pprint(count)


列印結果:

{' ': 12,
 ',': 1,
 'A': 1,
 'I': 1,
 'a': 4,
 'c': 3,
 'd': 2,
 'e': 6,
 'g': 1,
 'h': 2,
 'i': 6,
 'k': 2,
 'l': 2,
 'n': 6,
 'o': 1,
 'p': 1,
 'r': 4,
 's': 3,
 't': 5,
 'w': 2,
 'y': 1}

如果希望得到漂亮列印的文字作為字串,而不是顯示在螢幕上, 那可以呼叫 pprint.pformat().

#pprint.pprint(count)
#print(pprint.pformat(count))

這倆是等價的。

巢狀的字典和列表

對於現實生活中的情況 進行資料建模。當你對複雜的事物建模時,可能發現字典和列表中需要包含其他字典和列表,列表適用於包含一組有序的值,字典適合於包含關聯的鍵和值。

下面的程式使用字典包含其他字典,用來記錄誰為野餐帶來了什麼食物, totalBrought() 函式可以讀取這個資料結構,計算所有客人帶來的食物的總數。


allGuests = {'Alice':{'apples':5,'pretzels':12},
             'Bob':{'ham sandwiches':3, 'apples':3},
             'Carol':{'cups':3,'apple pies':1}}

def totalBrought(guests,item):
    numBrought = 0
    for k,v in guests.items():
        numBrought = numBrought + v.get(item,0)

    return numBrought

print(' - Apples '+str(totalBrought(allGuests,'apples')))
print(' - pretzels '+str(totalBrought(allGuests,'pretzels')))
print(' - cups '+str(totalBrought(allGuests,'cups')))
print(' - cakes '+str(totalBrought(allGuests,'cakes')))
print(' - ham sandwiches '+str(totalBrought(allGuests,'ham sandwiches')))
print(' - apple pies '+str(totalBrought(allGuests,'apple pies')))


列印結果:

 - Apples 8
 - pretzels 12
 - cups 3
 - cakes 0
 - ham sandwiches 3
 - apple pies 1


小結

  • 列表和字典,可以包含多個值,包括其他列表和字典。
  • 列表是有序的,字典是不排序的。字典中的值時通過鍵來訪問的。
  • 字典的鍵不只可以使用整數,可以用各種資料型別,整型、浮點型、字串或元組。