python編程基礎——基本數據類型之字典


字典是另一種可變容器模型,且可存儲任意類型對象。


定義

字典的每個鍵值(key=>value)對用冒號(:)分割,每個對之間用逗號(,)分割,整個字典包括在花括號({})中 。其中鍵值是唯一的,不能重複。值格式如下所示:

#創建方法一 直接創建
>>> dic={'zhangsan':'S001','lisi':'S002','wangwu':'S003'}
>>> dic
{'zhangsan': 'S001', 'lisi': 'S002', 'wangwu': 'S003'}

#創建方法二 利用元祖/列表
>>> dic=(['zhangsan','S001'],['lisi','S002'])
>>> dict(dic)
{'zhangsan': 'S001', 'lisi': 'S002'}
#或者用這樣的方法
>>> dic=dict(name='zhangsan',age=23)
>>> dic
{'name': 'zhangsan', 'age': 23}

#創建方法三 使用fromkeys
>>> help(dict.fromkeys)
Help on built-in function fromkeys:

fromkeys(iterable, value=None, /) method of builtins.type instance
    Create a new dictionary with keys from iterable and values set to value.
# 可以看到使用formkeys可以批量創建不同keys單值一樣的字典,其中的迭代器可以是列表也以是元組。
>>> dic={}.fromkeys(('a','s','d'),1)
>>> dic
{'a': 1, 's': 1, 'd': 1}
>>> dic={}.fromkeys(['a','s','d'],1)
>>> dic
{'a': 1, 's': 1, 'd': 1}

操作

訪問及修改

字典類型的對象是以鍵值對的形式存儲數據的。所以,只要知道鍵,就能找到值。本質上就是一種映射關係。

{'a': 10, 's': 10, 'd': 10}
>>> dic['a']
10
>>> dic['a']=9
>>> dic
{'a': 9, 's': 10, 'd': 10}

長度len()

返回字典(d)中的鍵值對的數量。

>>> dic
{'a': 9, 's': 10, 'd': 10}
>>> len(dic)
3

查找及刪除

key in d, 檢查字典(d) 中是否含有鍵爲key的項。

# 修改
>>> dic={'a': 9, 's': 10, 'd': 10}
>>> 'a' in dic
True

del d[key], 刪除字典(d) 的鍵(key) 項(將該鍵值對刪除) 。

# 刪除指定項
>>> del dic['a']
>>> dic
{'s': 10, 'd': 10}

# 刪除整個字典
>>> del dic
>>> dic
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'dic' is not defined

字符串格式化輸出

關於字符串格式化輸出問題在字符串一章已經涉及過,這裏主要探究通過字典實現格式化字符串對目的。

>>> print("c's value is %(c)s. a's value is %(a)s" %dic)
c's value is 7. a's value is 3

字典的函數

跟前面所講述對其他對象類似,字典也有一些函數,通過這些函數我們能夠實現對字典對操作。

copy和deepcopy

在python中,“ = ” 是一種引用的複製,這一點在數字那一張也有詳細從內存上討論過,這裏我們再次回顧一下:

>>> a=2
>>> b=a
>>> id(a)
140707635106656
>>> id(b)
140707635106656

由於python中的變量都是採用的引用語義,數據結構可以包含基礎數據類型,導致了在python中每個變量中都存儲了這個變量的地址,而不是值本身。
同樣如果如果僅僅是單純對使用 “ = ” 來複制的話,就像在列表以及數字中提及的那樣,複製過來的僅僅是抵制飲用而已。

>>> dic={}.fromkeys(('asd','qwe'),1)
>>> copy_dic=dic
>>> id(dic)
1654004468616
>>> id(copy_dic)
1654004468616

這樣做會有什麼和後果呢?假如我們希望在複製的內容中做一些修改將結果輸出,而原來對內容並不希望改變。由於使用對是地址引用,因此在改變copy_dic的時候,dic也變了。

>>> copy_dic['asd']=2
>>> dic
{'asd': 2, 'qwe': 1}

如何做到複製對是值而不是對象對引用呢? 這時候copy()大喊一聲:我來了!

>>> id(dic)
1654004468616
>>> copy_dic=dic.copy()
>>> id(copy_dic)
1654004466024
>>> dic
{'asd': 2, 'qwe': 1}
>>> copy_dic
{'asd': 2, 'qwe': 1}

我們驚奇的發現,通過copy()後,複製對是值而不是地址了。可是還有一個問題:
>>> dic={'name':'zhang','learn':['math','physics','PE']}
>>> copy_dic=dic.copy()
>>> copy_dic['learn'].remove('PE')
>>> copy_dic
{'name': 'zhang', 'learn': ['math', 'physics']}
>>> dic
{'name': 'zhang', 'learn': ['math', 'physics']}

誒?woc什麼鬼,難道copy()的不對嗎?讓我來叫id()來查查看:
>>> id(dic)
1654004468400
>>> id(copy_dic)
1654004465808

是不是更加迷惑了,別急,讓我們想想問題出在哪了,首先我們通過copy()複製過來的一定是值而不是地址,對於list來說它的值就是list對引用,即雖然兩個字典不是同一個地址塊,但兩個字典中對列表對應的是同一個列表區域。

>>> id(dic['learn'])
1654004267976
>>> id(copy_dic['learn'])
1654004267976

怎麼辦呢?deepcopy()這時候過來了,老哥不行了呀,換我來吧:
>>> import copy
>>> dic={'name':'zhang','learn':['math','physics','PE']}
>>> copy_dic=copy.deepcopy(dic)
>>> copy_dic['learn'].remove('PE')
>>> dic
{'name': 'zhang', 'learn': ['math', 'physics', 'PE']}
>>> copy_dic
{'name': 'zhang', 'learn': ['math', 'physics']}

關於深淺拷貝還可以參見python——賦值與深淺拷貝



clear清除

簡言之,clear()的作用就是將字典內容清空。我們先看一下clear的函數說明:

Help on method_descriptor:

clear(...)
    D.clear() -> None.  Remove all items from D.

讓我們來看一下clear的運行結果,可以發現通過使用clear()主動將字典中的內容刪除掉了,當然也可以直接用“dic={}”將dic的引用轉向“{}”,原來的內容沒有引用則變成了垃圾,python會主動回收。當然,如果不想用了也可以直接用del刪掉。

>>> dic
{'name': 'zhang', 'learn': ['math', 'physics', 'PE']}
>>> dic.clear()
>>> dic
{}

get和setdefult

get()

先讓我們看一下get()的函數說明:

>>> help(dict.get)
Help on method_descriptor:

get(self, key, default=None, /)
    Return the value for key if key is in the dictionary, else default.

可以看到如果key在字典中,則返回key的值,否則返回default。

>>> dic={'name':'zhang','learn':['math','physics','PE']}
>>> dic.get('name','null')
'zhang'
>>> dic.get('age','null')
'null'

dict.get()相對於dict[i]而言,沒有那麼嚴格。dict.get()可以對字典中沒有存在的鍵返回初值或着不返回。但dict[i]則會直接報錯。



setdefault()

先讓我們看一下setdefult()的函數說明:

>>> help(dict.setdefault)
Help on method_descriptor:

setdefault(self, key, default=None, /)
    Insert key with a value of default if key is not in the dictionary.
    Return the value for key if key is in the dictionary, else default.

與get不同的是,如果key不在字典中,則插入值爲default的key。如果key在字典中,則返回key的值,否則返回default。

>>> dic
{'name': 'zhang', 'learn': ['math', 'physics', 'PE']}
>>> dic.setdefault('name','null')
'zhang'
>>> dic.setdefault('age','null')
'null'
>>> dic
{'name': 'zhang', 'learn': ['math', 'physics', 'PE'], 'age': 'null'}
>>> dic.setdefault('sex')
>>> dic
{'name': 'zhang', 'learn': ['math', 'physics', 'PE'], 'age': 'null', 'sex': None}

items, keys, values

老規矩,先讓我們看一下函數說明:

>>> help(dict.items)
Help on method_descriptor:

items(...)
   D.items() -> a set-like object providing a view on D's items
   # 一個類似於集合的對象,提供D的項目視圖

我們可以使用dict.items()來遍歷字典中的數據,當然如果我們直接使用list得到的是dict的鍵,通過dict.items()提供的視圖我們可以將整個字典轉化爲list。

>>> dic=dict(name="wangwu",age=25)
>>> dic.items()
dict_items([('name', 'wangwu'), ('age', 25)])

>>> for i,j in dic.items():
...     print(i,":",j)

name : wangwu
age : 25

>>> list(dic)
['name', 'age']
>>> list(dic.items())
[('name', 'wangwu'), ('age', 25)]

相似的keys和values提供的則分別是鍵和值的視圖。

>>> dic.keys()
dict_keys(['name', 'age'])
>>> dic.values()
dict_values(['wangwu', 25])

pop和popitem

在list中我們有提到過pop和remove,其中list.pop(i)是刪除指定索引元素,而list.remove(x)則是刪除指定元素。
字典中我們也有兩個類似的刪除方式pop和popitem,在pop中是指刪除指定鍵和對應的值,返回值。在popitem中則是隨機刪除一組鍵值並返回(一般是隨機加載出來字典的最後一個元素)。

>>> dic
{'name': 'wangwu', 'age': 25}
# pop
>>> dic.pop("name")
'wangwu'
#popitem
>>> dic.popitem()
('age', 25)

update

首先讓我們先來看一下函數說明:

>>> help(dict.update)
Help on method_descriptor:

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]
    #如果E存在且有.key()方法,則執行: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
    #如果E存在且沒有.key()方法,則執行:for k, v in E: D[k] = v
    In either case, this is followed by: for k in F:  D[k] = F[k]

可以看出首先這個函數是沒有返回值的,它的作用就是更新字典。其參數是字典或者某種可以迭代的對象。
# 字典更新字典
>>> E=dict(name="wangwu")
>>> D=dict(sex=22)
# 方式一
>>> D.update(E)
>>> D
{'sex': 22, 'name': 'wangwu'}
# 方式二
>>> E=(["sex",20],["lang","python"])
>>> D.update(E)
>>> D
{'sex': 20, 'name': 'wangwu', 'lang': 'python'}
# 方式三
>>> D.update(name="zhangsan")
>>> D
{'sex': 20, 'name': 'zhangsan', 'lang': 'python'}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章