一文掌握Python集合的語法與應用

  • 2020 年 2 月 23 日
  • 筆記

6.1 基本概念

Python語言中的集合是無序的、可變的容器類對象,所有元素放在一對大括弧中,元素之間使用逗號分隔,同一個集合內的每個元素都是唯一的,不允許重複。

集合中只能包含數字、字元串、元組等不可變類型或可哈希的數據,不能包含列表、字典、集合等可變類型或不可哈希的數據,包含列表等可變類型數據的元組也不能作為集合的元素。

集合中的元素是無序的,元素存儲順序和添加順序並不一致,先放入集合的元素不一定存儲在前面。集合中的元素不存在「位置」或「索引」的概念,不支援使用下標直接訪問指定位置上的元素,不支援使用切片訪問其中的元素,也不支援使用random中的choice()函數從集合中隨機選取元素,但支援使用random模組中的sample()函數隨機選取部分元素。

6.2 集合創建與刪除

除了把若干可哈希對象放在一對大括弧內創建集合,也可以使用set()函數將列表、元組、字元串、range對象等其他可迭代對象轉換為集合,如果原來的數據中存在重複元素,在轉換為集合的時候只保留一個,自動去除重複元素。如果原序列或可迭代對象中有可變類型的數據,無法轉換成為集合,拋出TypeError異常並提示對象不可哈希。當不再使用某個集合時,可以使用del語句刪除整個集合。下面的程式碼演示了創建集合的不同形式和方法。

6.3 集合常用方法

Python內置集合類set支援內置函數len()、max()、min()、sum()、sorted()、map()、filter()、enumerate()、all()、any()等內置函數和並集運算符「|」、交集運算符「&」、差集運算符「-」、對稱差集運算符「^」、成員測試運算符「in」、同一性測試運算符「is」,不支援內置函數reversed(),相關內置函數的介紹詳見本書第2章。另外,set類自身還提供了大量方法,如表6-1所示。

表6-1 Python內置集合類提供的方法

方法

功能簡介

add(…)

往當前集合中增加一個可哈希元素,如果集合中已經存在該元素,直接忽略該操作,如果參數不可哈希,拋出TypeError異常並提示參數不可哈希。該方法沒有返回值

clear()

刪除當前集合對象中所有元素,沒有返回值

copy()

返回當前集合對象的淺複製

difference(…)

接收一個或多個集合(或其他可迭代對象),返回當前集合對象與所有參數對象的差集,功能類似於差集運算符-

difference_update(…)

接收一個或多個集合(或其他可迭代對象),從當前集合中刪除所有參數對象中的元素,對當前集合進行更新,該方法沒有返回值,功能類似於運算符-=

discard(…)

接收一個可哈希對象作為參數,從當前集合中刪除該元素,如果參數元素不在當前集合中則直接忽略該操作。該方法沒有返回值

intersection(…)

接收一個或多個集合對象(或其他可迭代對象),返回當前集合與所有參數對象的交集,功能類似於交集運算符&

intersection_update(…)

接收一個或多個集合(或其他可迭代對象),使用當前集合與所有參數對象的交集更新當前集合對象,功能類似於運算符&=

isdisjoint(…)

接收一個集合(或其他可迭代對象),如果當前集合與參數對象的交集為空則返回True

issubset(…)

接收一個集合(或其他可迭代對象),測試當前集合是否為參數對象的子集,是則返回True,否則返回False,等價於關係運算符<=

issuperset(…)

接收一個集合(或其他可迭代對象),測試當前集合是否為參數對象的超集,是則返回True,否則返回False,等價於關係運算符>=

pop()

不接收參數,刪除並返回當前集合中的任意一個元素,如果當前集合為空則拋出KeyError異常

remove(…)

從當前集合中刪除一個元素,如果參數指定的元素不在集合中,拋出KeyError異常

symmetric_difference(…)

接收一個集合(或其他可迭代對象),返回當前集合與參數對象的對稱差集,等價於對稱差集運算符^

symmetric_difference_update(…)

接收一個集合(或其他可迭代對象),使用當前集合與參數對象的對稱差集更新當前集合,等價於運算符^=

union(…)

接收一個或多個集合(或其他可迭代對象),返回當前集合與所有參數對象的並集,功能類似於並集運算符|

update(…)

接收一個或多個集合(或其他可迭代對象),把參數對象中所有元素添加到當前集合對象中,沒有返回值

6.3.1 原地增加/刪除集合元素

集合方法add()、update()可以用於向集合中添加新元素,difference_update()、intersection_update()、pop()、remove()、symmetric_difference_update()、clear()可以用於刪除集合中的元素,這些方法都是對集合對象原地進行修改。下面的程式碼演示了部分方法的用法。

6.3.2 計算交集/並集/差集/對稱差集返回新集合

集合方法difference()、intersection()、union()分別用來返回當前集合與另外一個或多個集合(或其他可迭代對象)的差集、交集、並集,方法symmetric_difference()用來返回當前集合與另外一個集合(或其他可迭代對象)的對稱差集。下面的程式碼演示了這幾個方法的用法。

6.3.3 集合測試

集合方法issubset()、issuperset()、isdisjoint()分別用來測試當前集合是否為另一個集合的子集、是否為另一個集合的超集、是否與另一個集合不相鄰(或交集是否為空)。下面的程式碼演示了這幾個方法的用法。

6.4 綜合例題解析

例6-1 編寫程式,求解買啤酒問題。一位酒商共有5桶葡萄酒和1桶啤酒,6個桶的容量分別為30升、32升、36升、40升和62升,並且只賣整桶酒,不零賣。第一位顧客買走了2整桶葡萄酒,第二位顧客買走的葡萄酒是第一位顧客的2倍。計算有多少升啤酒。

解析:逐個遍歷每一桶並假設是啤酒,從剩餘幾桶中任選兩桶並假設是第一位顧客購買的葡萄酒的數量,如果這兩桶啤酒恰好是剩餘幾桶總容量的三分之一,說明本次假設的啤酒是正確的。

例6-2 編寫程式,輸入包含任意數據的列表,檢查列表中數據的重複情況。如果列表內所有元素都是一樣的,輸出「完全重複」;如果列表內所有元素都互相不一樣,輸出「完全不重複」;否則輸出「部分重複」。

解析:利用集合能夠自動去除重複的特點,把列錶轉換為集合,然後比較列表和集合的長度。如果二者相等,表示原列表中的數據無重複;如果轉換為集合後只有一個元素,表示原列表中的數據是完全重複的;如果轉換為集合後數據數量減少但沒有減少為1,說明原列表中的數據有一部分是重複的。