1. 程式人生 > >笨方法學Python 習題40:字典,可愛的字典

笨方法學Python 習題40:字典,可愛的字典

題目

聽聞坊間流傳,python 中的字典(dict)是不不少人喜愛的一種基礎資料型別。相比列表(list)雖然同樣是可變的容器型基礎資料型別,但是字典在獲取任何資料時的速度都是飛快,而列表則會隨著長度的增加而不斷損失速度。也許正是如此本題的題目才會是“可愛的”吧。下面我們將首先學習字典的基礎知識,然後進行一個對應的練習。

新知識

字典(dict,全稱 dictionary)在不同程式語言中的名字不同例如 “hash” 、“map”,它的形式很像我們使用的字典,有一個鍵 key 表示一個名字,還有一個值 value 表示鍵的資料。把鍵值對(key-value)方在大括號中就就是我們說的字典了。 不過我們先來看看列表和字典的區別。使用列表我們可以做下面的事情:

>>> things = ['a', 'b', 'c', 'd']
>>> print(things[1])
b
>>> things[1] = 'z'
>>> print(things[1])
z
>>> print(things)
['a', 'z', 'c', 'd']
>>>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

我們想要使用列表中的一個元素,可以使用數字作為索引找到這個元素。而字典幾乎任何東西作為“索引”,其實也就是 key 只不過需要注意 key 必須是不可變的資料型別(可參考 37題答案——資料型別

>>> stuff = {'name': 'Zed', 'age': 36'height': 6*12+2}
>>> print(stuff['name'])
Zed
>>> print(stuff['age'])
36
>>> print(stuff['height'])
74
>>> stuff['city'] = "San Francisco"
>>> print(stuff['city'])
San Francisco
>>>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

字串是不能改變的,例如我收錢幫你買了一臺 ’bpple’ 牌的 ‘NacBook’ 筆記本恐怕你就要著急了。字串如果改變意思就不一樣了,正如真正的字典一樣。而數字也是不可變的,又如我給你換了臺 2028 款的 MacBook,恐怕你不也還是不會安心到那裡去(會不會因為我成功預測 apple 公司十年後的產品而免費得到一臺呢 哈哈),所以數字也是可以用來作為字典的鍵

>>> stuff[1] = "Wow"
>>> stuff[2] = "Neato"
>>> print(stuff[1])
Wow
>>> print(stuff[2])
Neato
>>>print(stuff)
{'city': 'San Francisco', 2: 'Neato',
    'name': 'Zed', 1: 'Wow', 'age': 36,
    'height': 74}
>>>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

注意到了麼,字典中鍵值對的順序是不固定的,它是無序的。此外,作為容器字典是可進可出的,我們可以使用 del 刪除某一個鍵值對

>>> del stuff['city']
>>> del stuff[1]
>>> del stuff[2]
>>> stuff
{'name': 'Zed', 'age': 36, 'height': 74}
>>>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

剩下的就是基礎練習和加分練習了。

加分練習

  1. 在 Python 文件中找到 dictionary (又叫 dicts,dict)的相關內容,學著掌握 dict 的更多操作。
  2. 找到一些 dict 無法做到的事情。例如比較重要的是個就是 dict 的內容是無序的,可以檢查一下是否真是這樣。
  3. 試著把 for-loop 執行到 dict 上面,然後試著在 for-loop 中使用 dict 的 items() 函式,看看會有什麼樣的結果。

我的答案

40.0 基礎練習

# 建立了一個包含多個城市名稱的字典
cities = {'CA': 'San Francisco', 'MI': 'Detroit', 'FL': 'Jacksonville'}

# 為 cities 增加兩個新的城市。
cities['NY'] = 'New York'
cities['OR'] = 'Portland'

# 建立一個函式,從字典中通過簡寫獲得城市名稱
def find_city(themap, state):    # map 是內建函式 所以使用了 themap
    if state in themap:
        return themap[state]
    else:
        return "Not found."

# ok pay attetion!
cities['_find'] = find_city

# 原文中 
#    print "State? (ENTER to quit)", 
#    state = raw_input("> ")
#
# 這種寫法 python 3 似乎做不到了,參考列印的結果改下成了下面的寫法
while True:
    state = input("State? (ENTER to quit) > ")
    if not state: break

    # this line is the most important ever! study!
    # 據說搞不懂的可以看看下一題
    city_found = cities['_find'](cities, state)
    print(city_found)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

這裡寫圖片描述

40.1 字典的幫助文件

檢視文件的方法大家應該都還記得吧,我的到了下面這些資訊,按照慣例,為列出有下劃線的方法

class dict(object)
 |  dict() -> new empty dictionary 
 |            建立一個新的空字典
 |  dict(mapping) -> new dictionary initialized from a mapping object's 
 |      (key, value) pairs
 |
 |  dict(iterable) -> new dictionary initialized as if via:
 |      d = {}
 |      for k, v in iterable:
 |          d[k] = v
 |      從可迭代物件建立字典
 |
 |  dict(**kwargs) -> new dictionary initialized with the name=value pairs
 |      in the keyword argument list.  For example:  dict(one=1, two=2)
 |      使用關鍵詞引數建立
 |
 |  Methods defined here:
 |
 |  clear(...)
 |      D.clear() -> None.  Remove all items from D.
 |                  清空字典
 |
 |  copy(...)
 |      D.copy() -> a shallow copy of D
 |                  和列表類似是淺拷貝,如果子內容的列表或字典改變,
 |                   拷貝體的子內容也會改變。深拷貝則不會。
 |
 |  fromkeys(iterable, value=None, /) from builtins.type
 |      Returns a new dict with keys from iterable and values  equal to value.
 |        生成一個新字典,其鍵來自可迭代物件,預設值是 None
 |
 |  get(...)
 |      D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
 |          獲取若干鍵的值,如果鍵不存在則返回 None
 |
 |  items(...)
 |      D.items() -> a set-like object providing a view on D's items
 |                  返回一個包含 鍵-值 的元祖的列表
 |
 |  keys(...)
 |      D.keys() -> a set-like object providing a view on D's keys
 |                  返回一個包含鍵的列表
 |
 |  pop(...)
 |      D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
 |      If key is not found, d is returned if given, otherwise KeyError is raised
 |                 移除指定的鍵值對,並返回值
 |
 |  popitem(...)
 |      D.popitem() -> (k, v), remove and return some (key, value) pair as a
 |      2-tuple; but raise KeyError if D is empty.
 |                  移除一對鍵值對,並以元祖返回鍵值對,
 |                  如果字典為空,則返回 KeyError
 |
 |  setdefault(...)
 |      D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
 |          接受兩個值,如 k,d 如果 k 是已經存在的鍵則返回值,
 |            如果鍵不存在,則 k 為鍵, d 為值存入字典
 |
 |  update(...)
 |      D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
 |      If E is present and has a .keys() method, then does:  for k in E: D[k] = E[k]
 |      If E is present and lacks a .keys() method, then does:  for k, v in E: D[k] = v
 |      In either case, this is followed by: for k in F:  D[k] = F[k]
 |          把字典或可迭代物件更新到當前字典
 |
 |  values(...)
 |      D.values() -> an object providing a view on D's values
 |            返回只包含值的列表
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

40.2 字典不能做的事情

和列表相比,可以看到字典本身就沒有任何和順序有關的操作,比如從前端加如元素、排序等

40.3 對字典使用 for 迴圈

總之,先按照要求做做看把。

d = {'1': 'a', '2': 'b', '3': 'c', '4':'d'}

# 使用 for 迴圈遍歷字典
for k in d:
    print("當前的鍵是 %r, 它的值是:%r" % (k, d.get(k)))


for k, v in d.items():
    print(k, v)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

字典在 for 迴圈中只能遍歷出鍵,而不會遍歷出對應的值。 遍歷 d.items() 時則會獲取到鍵值對組成的元祖,因此需要兩個變數分別獲取鍵和值。

返回目錄