iT邦幫忙

2

【Python 超入門】(15)運用字典及集合幫你做快速的查找

字典和集合是python內建很好用的資料型別,它可以快速查詢一個元素是否在裡面
最近有看到一個python初學的教學網站,叫做「自學成功道」,
裡面很淺顯易懂的教了字典的使用及語法介紹,
分享給大家

教學: Python字典(dictionary)基礎與16種操作

這邊就不做太多贅述,用一些自己的話補充

變數型態- dict: 就是查資料的字典

想到字典,你會聯想到國語字典?英語字典?

當你不知道一個詞語的意思時,
你會輸入關鍵字(key)在字典中查詢,
然後便可以查詢那個詞語的解釋(value)。
這種查詢的概念便類似python的字典(dict),
python的dict由一組key:value組成放在大括號裡,
例如:

D = {'s':"黑桃", 'h':"紅心", 'd':"方塊", 'c':"梅花"}

此時我們便建立了一本字典,
可以想成是「詞語's'的意思為"黑桃"」,「詞語'h'的意思為"紅心"」…。
當我們想要查詢某個字的意思,
便可以用中括號放入關鍵字做查詢,如:

>>> D['s']
'黑桃'
>>> D['d']
'方塊'

其實小馬覺得列表可以想成是一種特別的字典,
只是列表的查詢一定是用「index」(位置)去查,
像是當你寫

pocket = ['任意門', '縮小燈', '時光機'] 
print(pocket[1])

這邊pocket[1]其實就是查說放在列表的第一個位置的元素是什麼

而字典就更廣了,「整數」(int)、「浮點數」(float)、「字串」(str)、「布林值」(bool)、「元組」(tuple)都可以當做是key來查詢(列表不能當key)

變數型態- set: 像是數學上講的集合

至於set是什麼呢?set其實就是數學上講的集合

  • 放在集合裡面的元素順序不重要
  • 放在集合內的元素不會重複
    例如說宣告{1,2,3}{2,3,1}{1,1,2,2,3}指的全部都是同一個集合

其實字典也具有這樣的特性:

  • key值的順序不重要
  • key值不會重複

看幾個例子即可明白,舉例來說我們宣告兩本字典,
裡面的內容都一樣,但是順序對調,
==判斷會將兩本字典視為相同內容(比較: 若是列表與元組的元素順序不同即視為不同)

D1 = {'s':"黑桃", 'h':"紅心", 'd':"方塊", 'c':"梅花"}
D2 = {'d':"方塊", 'c':"梅花", 's':"黑桃", 'h':"紅心"}
print(D1 == D2) # True

另外,若我們宣告下列三個集合,
程式則會判斷這三個集合都是相同的

s1 = {1,2,3}
s2 = {2,3,1}
s3 = {1,1,2,2,3}
print(s1 == s2) # True
print(s2 == s3) # True
print(s3) # {1, 2, 3}

集合運用: 去除列表中重複的元素

由於set()具有去除重複的特性,我們可以很輕易的將陣列中重複的元素去除
以下包裝成函數,
可以去除列表中重複的元素,並持列表元素原來的順序:

def removeDuplicate(seq):
    return sorted(set(seq), key = seq.index)

mylist = removeDuplicate(["a", "b", "a", "c", "c"])
print(mylist) #["a", "b", "c"]

快速查找元素

我們知道in關鍵字可以查詢一個元素是否在一個容器裡面,
然而在列表中查詢與和集合中查詢的效率會差很多,
若有需要快速查詢的效果就用集合吧。

以下示範查詢「9999」這個數字是否在列表跟集合中的時間差別:
簡介一下timeit模組,
它可以幫助我們測量一小段程式碼的執行時間,
第一個參數用字串包起來,寫欲執行的程式碼,
參數number是執行這段程式碼幾次(因為有時候測試程式太小,執行時間太短,就需要執行多次一點以看出效能差異)
參數globals=globals()說明執行的程式碼會用到全域變數。

import timeit
List = list(range(10000))
Set = set(range(10000))
print(timeit.timeit('9999 in List', number=10000, globals=globals()))
print(timeit.timeit('9999 in Set', number=10000, globals=globals()))

結果可以看到在set裡面搜索比在list內搜索快了數千倍:

0.8512682000000069
0.0004332000000033531

尚未有邦友留言

立即登入留言