13 set應用實戰

  • set是python內建的一種collection
  • 既然是collection,我們就可以把它當資料庫看,所以會依序介紹作為資料庫最基礎的幾個part:
    • 如何建立?
    • 如何增、刪、查、改?
  • 這些基礎會了後,就確認一下是否為mutable物件,來決定如何做copy
  • 接著就開始介紹如何loop他(用for, comprehension)
  • 最後就是補齊這個object還沒介紹到的methods
  • 實戰的部分,就會以”How to…“的方式整理常見的需求

13.1 定義set

  • 集合就是只有key,沒有value的dictionary
  • 例如,以下是dictionary
my_dict = {
  'a': 1,
  'b': 5
}
print(my_dict)
#> {'a': 1, 'b': 5}
  • 而,以下就是set
my_set = {'a', 'b'}
print(my_set)
#> {'a', 'b'}
  • set的特點,其實和dictionary的key的特點一樣(也和數學上的集合的特點一樣),就是’唯一’和’無序’。
  • 唯一就是key值唯一,你多給他重複的key,他也幫你刪掉。無序就是你每次print的時候,他順序都會亂跳,所以你有不能用index的方法來獲取set裡面的element

13.2 [查] 只能用for loopin

  • 因為set又沒有list/tuple的index,也沒有dictionary的key,所以你既不能用set1[index]來取資料,也不能用set1['key']來取資料
  • 所以,只能做兩件事:
    • 用for迴圈來loop看看總共有哪些item
    • in來確認,你指定的item有沒有在這個set裡面
thisset = {"apple", "banana", "cherry"}

for x in thisset:
  print(x)
#> apple
#> banana
#> cherry
  • check “banana”是否在這個set中
thisset = {"apple", "banana", "cherry"}

print("banana" in thisset)
#> True

13.3 [改] set無法做修改

  • set無法做修改的原因,是因為他無法取出你指定的那個item,所以他無法像list那樣,用list1[index] = new_value,也無法像dictionary那樣,用dic1['key'] = new_value來做修改
  • 但set可以做刪除和新增。所以如果一個set是{"apple", "banana", "orange"},那我想把”banana”改成”kiwi”,那就是刪除”banana”,再新增”kiwi”就好

13.4 [刪] .remove().discard()

  • .remove().discard()的差別,是在remove一個不存在的值時,他會跳error,但discard一個不存在的值時,他就裝沒事而已
thisset = {"apple", "banana", "cherry"}

thisset.remove("banana")

print(thisset)
#> {'apple', 'cherry'}
thisset = {"apple", "banana", "cherry"}

thisset.remove("kiwi")
#> Error in py_call_impl(callable, dots$args, dots$keywords): KeyError: 'kiwi'
#> 
#> Detailed traceback:
#>   File "<string>", line 1, in <module>
thisset = {"apple", "banana", "cherry"}

thisset.discard("banana")

print(thisset)
#> {'apple', 'cherry'}
thisset = {"apple", "banana", "cherry"}

thisset.discard("kiwi")

print(thisset)
#> {'apple', 'banana', 'cherry'}

13.5 [增] .add().update()

13.5.1 增加一個item用.add()

thisset = {"apple", "banana", "cherry"}

thisset.add("orange")

print(thisset)
#> {'apple', 'orange', 'banana', 'cherry'}

13.5.2 增加多個item用.update()

thisset = {"apple", "banana", "cherry"}
tropical = {"pineapple", "mango", "papaya"}

thisset.update(tropical)

print(thisset)
#> {'apple', 'banana', 'pineapple', 'cherry', 'papaya', 'mango'}
  • 如果update的東西,裡面有和原本重複的值,那就只會留一個,因為set就是unique
thisset = {"apple", "banana", "cherry"}
tropical = {"apple", "banana", "papaya"}

thisset.update(tropical)

print(thisset)
#> {'apple', 'banana', 'cherry', 'papaya'}

13.6 [mutable] 請愛用.copy()

  • set也是mutable,所以以下慘劇會重現:
set1 = {"apple", "banana", "orange"}
set1_copy = set1  

set1_copy.remove("apple")

print(set1_copy)
#> {'orange', 'banana'}
print(set1)
#> {'orange', 'banana'}
  • 記得用.copy()來解決問題
set1 = {"apple", "banana", "orange"}
set1_copy = set1.copy()  

set1_copy.remove("apple")

print(set1_copy)
#> {'orange', 'banana'}
print(set1)
#> {'apple', 'orange', 'banana'}

13.7 [loop] for

  • 這邊就沒什麼,你只能loop他的item:
set1 = {"apple", "banana", "orange"}
for item in set1:
  print(item)
#> apple
#> orange
#> banana

13.8 [loop] comprehension

  • set可以看成簡化版的dictionary,那既然可以做dictionary comprehension,就應該可以做set comprehension
set1 = {"apple", "banana", "orange"}
set2 = {item for item in set1}

print(set2)
#> {'apple', 'orange', 'banana'}

13.9 [特殊技] 集合運算

  • set可以做數學上的交集(&)、聯集(|)、差集(-)、補集(^)
s1 = {1,2,3,4}
s2 = {3,4,5,6}

print(s1 & s2)
#> {3, 4}
print(s1 | s2)
#> {1, 2, 3, 4, 5, 6}
print(s1 - s2) #是s1,但不是s2
#> {1, 2}
print(s1 ^ s2)
#> {1, 2, 5, 6}

13.10 [特殊技] 對list取unique

  • 例如我有一個list,我想取出unique的值:
l = [1,2,3,2,4,5,2]
l_unique = list(set(l))
print(l_unique)
#> [1, 2, 3, 4, 5]

13.11 [特殊技] 將字串中unique character轉成list

  • 這招蠻牛的,看一下例子就會了
my_string = "aabbcdefg"
string_to_set = set(my_string)
print(string_to_set)
#> {'a', 'g', 'e', 'b', 'f', 'c', 'd'}