高見龍

iOS app/Ruby/Rails Developer & Instructor, 喜愛非主流的新玩具 :)

Dictionary

字典

有的程式語言稱它叫"Hash Table",有的管它叫做"物件",基本上Python的Dictionary就長這個樣子:

1
eddie = {"first_name" : "eddie", "last_name" : "kao", "age" : 30}

List是用中括號,Dictionary則是使用大括號。Dictionary是由Key及Value之配對組合而成,順序不重要,但Key的大小寫有分別。跟List一樣,並不限定只能放同一種型態的資料。

Nested Dictionary

可以一層包一層..

1
author = { "name" : "eddie", "profile" : {"age" : 30, "tel" : "0928123456"} }

操作

來看看怎麼操作Dictionary。

取用

>>> my_dict = {'first_name': 'eddie', 'last_name': 'kao', 'age': 30}
>>> my_dict["first_name"]
'eddie'

新增

>>> my_dict = {'first_name': 'eddie', 'last_name': 'kao', 'age': 30}
>>> my_dict["weight"] = 80
>>> my_dict
{'first_name': 'eddie', 'last_name': 'kao', 'age': 30, 'weight': 80}

修改

>>> my_dict = {'first_name': 'eddie', 'last_name': 'kao', 'age': 30}
>>> my_dict['last_name'] = 'lee'
>>> my_dict
{'first_name': 'eddie', 'last_name': 'lee', 'age': 30}

刪除/清空

>>> my_dict = {'first_name': 'eddie', 'last_name': 'lee', 'age': 30}
>>> my_dict.clear()
>>> my_dict
{}
>>> del my_dict
>>> my_dict
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
NameError: name 'my_dict' is not defined

其它

  1. len : 檢查Dict的個數
  2. in / not in : 檢查是某個Key否存在該dictionary裡,回傳Boolean值
  3. copy : 將Dict之內容複製至另一變數
  4. has_key : 檢查是否有某個Key存在,回傳Boolean值
  5. items : 將Dict的key/value拆成Tuple之組合,回傳List
  6. keys : 將Dict的key部份回傳成List
  7. values : 將Dict的value部份回傳成List
  8. get : 取得指定key的值,第二個參數則是指定當找不到該key的導候所回傳的預設值

千言萬語,抵不過直接看程式碼:

>>> my_dict = {'first_name': 'eddie', 'last_name': 'kao', 'age': 30, 'weight': 80}
>>> len(my_dict)
4
>>> "eddie" in my_dict
False
>>> "first_name" in my_dict
True
>>> my_dict.has_key("age")
True
>>> my_dict.items()
[('first_name', 'eddie'), ('last_name', 'kao'), ('age', 30), ('weight', 80)]
>>> my_dict.keys()
['first_name', 'last_name', 'age', 'weight']
>>> my_dict.values()
['eddie', 'kao', 30, 80]
>>> my_dict.get("age")
30
>>> my_dict.get("height", 180)
180

本是同根生..

當在處理像List或是Dictionary這種比較複雜的資料結構的時候,有個新手可能常會犯的錯誤,我們來看一段程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
a = [1, 2, 3]
b = a

b[0] = 'x'

print b                  # ['x', 2, 3]
print a                  # ['x', 2, 3]

x = {"name" : "eddie"}
y = x

y["name"] = "kao"

print y                  # {"name" : "kao"}
print x                  # {"name" : "kao"}

i = j = [1, 2, 3]
i[0] = 'a'

print i                  # ['a', 2, 3]
print j                  # ['a', 2, 3]

注意到了嗎? 第2行、第10行、第17行的把某變數指定給另一個變數,但修改過新的變數的值之後,舊的變數的內容也跟著改了! 這是因為其實那個指定的動作只是個「請把b變數指向a」而已,所以遇到這種有"內容物"的資料型態,例如List跟Dictionary,當修改了b的值之後,a的值也跟著變了,因為他們兩個根本就是指到同一個地方。

這在Tuple就沒問題啦,因為Tuple是唯讀的。

那如果想讓兩個變數各保有原來的值而不互相影響呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
a = [1, 2, 3]
b = a[:]

print b          # [1, 2, 3]

b[0] = 'a'

print b          # ['a', 2, 3]
print a          # [1, 2, 3]

x = {"name" : "eddie"}
y = x.copy()

print y          # {'name' : 'eddie'}

y['name'] = 'kao'

print y          # {'name' : 'kao'}
print x          # {'name' : 'eddie'}

就是複製一份並指令給新的變數囉! 不過這遇上巢狀結構還是會有出狀況,因為[:]或是Dictiony內建的copy()方法只會複製最表層而已,內部巢狀結構還是會有一樣的狀況。如果要整個完全複製,請使用copy模組的deepcopy(),細節請參考官網文件:http://docs.python.org/library/copy.html

更多精彩內容,請見官網文件:http://docs.python.org/tutorial/datastructures.html

Comments