Python重要數據類型Dict和Set類型

1.Python之什么是dict

我們已經知道,listtuple 可以用來表示順序集合,例如,班里同學的名字:

['Adam', 'Lisa', 'Bart']

或者考試的成績列表:

[95, 85, 59]

但是,要根據名字找到對應的成績,用兩個 list 表示就不方便。

如果把名字和分數關聯起來,組成類似的查找表:

'Adam' ==> 95
'Lisa' ==> 85
'Bart' ==> 59

給定一個名字,就可以直接查到分數。

Python的 dict 就是專門干這件事的。用 dict 表示“名字”-“成績”的查找表如下:

d = {
    'Adam': 95,
    'Lisa': 85,
    'Bart': 59
}

我們把名字稱為key,對應的成績稱為valuedict就是通過 key 來查找 value

花括號 {} 表示這是一個dict,然后按照 key: value, 寫出來即可。最后一個 key: value 的逗號可以省略。

由于dict也是集合,len() 函數可以計算任意集合的大小:

>>> len(d)
3

注意: 一個 key-value 算一個,因此,dict大小為3

2.Python之訪問dict

我們已經能創建一個dict,用于表示名字和成績的對應關系:

d = {
    'Adam': 95,
    'Lisa': 85,
    'Bart': 59
}

那么,如何根據名字來查找對應的成績呢?

可以簡單地使用 d[key] 的形式來查找對應的 value,這和 list 很像,不同之處是,list 必須使用索引返回對應的元素,而dict使用key:

>>> print d['Adam']
95
>>> print d['Paul']
Traceback (most recent call last):
  File "index.py", line 11, in <module>
    print d['Paul']
KeyError: 'Paul'

注意: 通過 key 訪問 dictvalue,只要 key 存在,dict就返回對應的value。如果key不存在,會直接報錯:KeyError

要避免 KeyError 發生,有兩個辦法:

一是先判斷一下 key 是否存在,用 in 操作符:

if 'Paul' in d:
    print d['Paul']

如果 'Paul' 不存在,if語句判斷為False,自然不會執行 print d['Paul'] ,從而避免了錯誤。

二是使用dict本身提供的一個 get 方法,在Key不存在的時候,返回None:

>>> print d.get('Bart')
59
>>> print d.get('Paul')
None
3.Python中dict的特點

dict的第一個特點是查找速度快,無論dict有10個元素還是10萬個元素,查找速度都一樣。而list的查找速度隨著元素增加而逐漸下降。

不過dict的查找速度快不是沒有代價的,dict的缺點是占用內存大,還會浪費很多內容,list正好相反,占用內存小,但是查找速度慢。

由于dict是按 key 查找,所以,在一個dict中,key不能重復。

dict的第二個特點就是存儲的key-value序對是沒有順序的!這和list不一樣:

d = {
    'Adam': 95,
    'Lisa': 85,
    'Bart': 59
}

當我們試圖打印這個dict時:

>>> print d
{'Lisa': 85, 'Adam': 95, 'Bart': 59}

打印的順序不一定是我們創建時的順序,而且,不同的機器打印的順序都可能不同,這說明dict內部是無序的,不能用dict存儲有序的集合。

dict的第三個特點是作為 key 的元素必須不可變,Python的基本類型如字符串、整數、浮點數都是不可變的,都可以作為key。但是list是可變的,就不能作為 key

可以試試用list作為key時會報什么樣的錯誤。

不可變這個限制僅作用于keyvalue是否可變無所謂:

{
    '123': [1, 2, 3],  # key 是 str,value是list
    123: '123',  # key 是 int,value 是 str
    ('a', 'b'): True  # key 是 tuple,并且tuple的每個元素都是不可變對象,value是 boolean
}

最常用的key還是字符串,因為用起來最方便。

4.Python更新dict

dict是可變的,也就是說,我們可以隨時往dict中添加新的 key-value。比如已有dict

d = {
    'Adam': 95,
    'Lisa': 85,
    'Bart': 59
}

要把新同學'Paul'的成績 72 加進去,用賦值語句:

>>> d['Paul'] = 72

再看看dict的內容:

>>> print d
{'Lisa': 85, 'Paul': 72, 'Adam': 95, 'Bart': 59}

如果 key 已經存在,則賦值會用新的 value 替換掉原來的 value

>>> d['Bart'] = 60
>>> print d
{'Lisa': 85, 'Paul': 72, 'Adam': 95, 'Bart': 60}
5.Python之 遍歷dict

由于dict也是一個集合,所以,遍歷dict和遍歷list類似,都可以通過 for 循環實現。

直接使用for循環可以遍歷 dictkey

>>> d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
>>> for key in d:
...     print key
... 
Lisa
Adam
Bart

由于通過key 可以獲取對應的 value,因此,在循環體內,可以獲取到value的值。

6.Python中什么是set

dict的作用是建立一組 key 和一組 value 的映射關系,dictkey是不能重復的。

有的時候,我們只想要 dictkey,不關心 key 對應的 value,目的就是保證這個集合的元素不會重復,這時,set就派上用場了。

set 持有一系列元素,這一點和 list 很像,但是set的元素沒有重復,而且是無序的,這點和 dictkey很像。

創建 set 的方式是調用 set() 并傳入一個 listlist的元素將作為set的元素:

>>> s = set(['A', 'B', 'C'])

可以查看 set 的內容:

>>> print s
set(['A', 'C', 'B'])

請注意,上述打印的形式類似 list, 但它不是 list,仔細看還可以發現,打印的順序和原始 list 的順序有可能是不同的,因為set內部存儲的元素是無序的。

因為set不能包含重復的元素,所以,當我們傳入包含重復元素的 list 會怎么樣呢?

>>> s = set(['A', 'B', 'C', 'C'])
>>> print s
set(['A', 'C', 'B'])
>>> len(s)
3

結果顯示,set會自動去掉重復的元素,原來的list有4個元素,但set只有3個元素。

7.Python之 訪問set

由于set存儲的是無序集合,所以我們沒法通過索引來訪問。

訪問 set中的某個元素實際上就是判斷一個元素是否在set中。

例如,存儲了班里同學名字的set

>>> s = set(['Adam', 'Lisa', 'Bart', 'Paul'])

我們可以用 in 操作符判斷:

Bart是該班的同學嗎?

>>> 'Bart' in s
True

Bill是該班的同學嗎?

>>> 'Bill' in s
False

bart是該班的同學嗎?

>>> 'bart' in s
False

看來大小寫很重要,'Bart''bart'被認為是兩個不同的元素。

8.Python之 set的特點

set的內部結構和dict很像,唯一區別是不存儲value,因此,判斷一個元素是否在set中速度很快。

set存儲的元素和dictkey類似,必須是不變對象,因此,任何可變對象是不能放入set中的。

最后,set存儲的元素也是沒有順序的。

set的這些特點,可以應用在哪些地方呢?

星期一到星期日可以用字符串'MON', 'TUE', ... 'SUN'表示。

假設我們讓用戶輸入星期一至星期日的某天,如何判斷用戶的輸入是否是一個有效的星期呢?

可以用 if 語句判斷,但這樣做非常繁瑣:

x = '???' # 用戶輸入的字符串
if x!= 'MON' and x!= 'TUE' and x!= 'WED' ... and x!= 'SUN':
    print 'input error'
else:
    print 'input ok'

注意:if 語句中的...表示沒有列出的其它星期名稱,測試時,請輸入完整。

如果事先創建好一個set,包含'MON' ~ 'SUN'

weekdays = set(['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'])

再判斷輸入是否有效,只需要判斷該字符串是否在set中:

x = '???' # 用戶輸入的字符串
if x in weekdays:
    print 'input ok'
else:
    print 'input error'

這樣一來,代碼就簡單多了。

9.Python之 遍歷set

由于 set 也是一個集合,所以,遍歷 set 和遍歷 list 類似,都可以通過 for 循環實現。

直接使用 for 循環可以遍歷 set 的元素:

>>> s = set(['Adam', 'Lisa', 'Bart'])
>>> for name in s:
...     print name
... 
Lisa
Adam
Bart

注意: 觀察 for 循環在遍歷set時,元素的順序和list的順序很可能是不同的,而且不同的機器上運行的結果也可能不同。

10.Python之 更新set

由于set存儲的是一組不重復的無序元素,因此,更新set主要做兩件事:

一是把新的元素添加到set中,二是把已有元素從set中刪除。

添加元素時,用setadd()方法:

>>> s = set([1, 2, 3])
>>> s.add(4)
>>> print s
set([1, 2, 3, 4])

如果添加的元素已經存在于set中,add()不會報錯,但是不會加進去了:

>>> s = set([1, 2, 3])
>>> s.add(3)
>>> print s
set([1, 2, 3])

刪除set中的元素時,用setremove()方法:

>>> s = set([1, 2, 3, 4])
>>> s.remove(4)
>>> print s
set([1, 2, 3])

如果刪除的元素不存在set中,remove()會報錯:

>>> s = set([1, 2, 3])
>>> s.remove(4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 4

所以用add()可以直接添加,而remove()前需要判斷。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378

推薦閱讀更多精彩內容