>>>
>>> s=set('cheeseshoi')
>>> s
set(['c', 'e', 'i', 'h', 'o', 's'])
>>>
>>>
>>> t=frozenset('bookshop')
>>>
>>> t
frozenset(['b', 'h', 'k', 'o', 'p', 's'])
跟數學概念中的集合一樣,集合可以做join,-,包含,子集,超集等操作。
len(s) Return the cardinality of set s . x in s Test x for membership in s . x not in s Test x for non-membership in s . issubset ( other ) ¶ set <= other Test whether every element in the set is in other . set < other Test whether the set is a true subset of other , that is, set <= other and set != other . issuperset ( other ) ¶ set >= other Test whether every element in other is in the set. set > other Test whether the set is a true superset of other , that is, set >= other and set != other . union ( other , ... ) ¶ set | other | ...
Return a new set with elements from the set and all others.
Changed in version 2.6: Accepts multiple input iterables. intersection ( other , ... ) ¶ set & other & ...
Return a new set with elements common to the set and all others.
Changed in version 2.6: Accepts multiple input iterables. difference ( other , ... ) ¶ set - other - ...
Return a new set with elements in the set that are not in the others.
Changed in version 2.6: Accepts multiple input iterables. copy ( ) ¶ Return a new set with a shallow copy of s .
>>>
>>> set('posh')==set('shop')
True
>>>
>>> set('shop') <set('cheeseshop')
True
>>>
>>> set('bookshop')>=set('shop')
True
>>>
集合類型操作符:適合所有的集合類型 union() 或者 |:集合并集 & 集合交集intersection(). -:取集合相對於前者的差集,difference() symmetric_difference() ^ 對稱差
注意以上如果上述操作符的左邊是可變set而右邊是不可變set,則產生的結果為可變set,否則為不可變set
關於以上概念的數學涵義可以查離散數學。
以下操作符僅僅適用可變集合:
(Union) Update ( |= )
這個更新方法從已存在的集合中添加(可能多個)成員,此方法和update()等價.
>>> s = set('cheeseshop')
>>> u = frozenset(s)
>>> s |= set('pypi')
>>> s
set(['c', 'e', 'i', 'h', 'o', 'p', 's', 'y'])
保留/交集更新( &= )
保留(或交集更新)操作保留與其他集合的共有成員。此方法和intersection_update()等價.
>>> s = set(u)
>>> s &= set('shop')
>>> s
set(['h', 's', 'o', 'p'])
差更新 ( –= )
對集合s 和t 進行差更新操作s-=t,差更新操作會返回一個集合,該集合中的成員是集合s 去
除掉集合t 中元素後剩餘的元素。此方法和difference_update()等價.
>>> s = set(u)
>>> s -= set('shop')
>>> s
set(['c', 'e'])
對稱差分更新( ^= )
對集合s 和t 進行對稱差分更新操作(s^=t),對稱差分更新操作會返回一個集合,該集合中的成
員僅是原集合s 或僅是另一集合t 中的成員。此方法和symmetric_difference_update()等價.
>>> s = set(u)
>>> t = frozenset('bookshop')
>>> s ^= t
>>> s
set(['c', 'b', 'e', 'k'])
集合的內建方法: (所有的集合方法)
方法名稱 操作
s.issubset(t) 如果s 是t 的子集,則返回True,否則返回False
s.issuperset(t) 如果t 是s 的超集,則返回True,否則返回False
s.union(t) 返回一個新集合,該集合是s 和t 的並集
s.intersection(t) 返回一個新集合,該集合是s 和t 的交集
s.difference(t) 返回一個新集合,該集合是s 的成員,但不是t 的成員
s.symmetric_difference(t) 返回一個新集合,該集合是s 或t 的成員,但不是s 和t 共有的成員
s.copy() 返回一個新集合,它是集合s 的淺複製
以下內容為轉載:
set自python2.4中引入後,經過了多次的發展,在2.6中包括內建資料類型set、frozenset和基於字典的set、 immutableset,後者作為前面版本的相容,在2.6中已經不提倡使用。網路上現在已經有大量的關於set與fronzset的的文章,但是現有 文章對於set和fronzenset分別在何時使用,兩者的效率對比如何,介紹甚少。本文將從實際測試和源碼分析兩個角度就此進行分析。
一 只能用set
當集合對象會被改變時(例如添加、刪除元素等),只能使用set
二 只能用frozenset
一般來說使用fronzet的地方都可以使用set,除了以下兩種情況:
(1)作為可雜湊對象使用
set和frozensdet最本質的區別是前者是可變的、後者是不可變的,這就導致了set是不可雜湊的,而frozenset是可雜湊的。因此當需要將集合作為字典的索引值等需要可雜湊對象的情況時,只能使用frozenset
(2)不希望集合被更改
python中包括list在內的大部分內型在進行參數傳遞時都採用的引用傳遞,這樣函數對傳入參數的改變將引用參數本身。當我們不希望函數改變集合時我們需使用frozenset
三 set與frozenset的運行效率比較
我們先產生一個10w的list,然後分別使用set和frozenset來構造集合,運行1w次。通過多次測試發現,資料波動較大。無法說明set和frozenset到底哪個效率高。
四 源碼分析
既然通過直接測試無法得到高低之分,那麼我們從源碼來著手分析。 python的內建內型的實現都在object中,set和frozenset也不例外,兩者都在Object/setobject.c中實現。
通過查看PySet_Type和PyFrozenSet_Type可以知道set使用set_new分配空間,set_init來初始化集 合;frozenset使用frozenset_new分配空間,未提供初始化函數。set和frozeset的tp_alloc與tp_free函數相 同,分別為PyType_GenericAlloc和PyObject_GC_Del。由於fronzeset沒有提供初始化函數,所以資料的初始化是在 分配空間時同步進行。
(一)set初始化
set_new函數直接調用make_new_set來產生為新的集合申請空間(傳遞給make_new_set的第二個參數為NULL)。空間的分配有 兩種方法:1 如果全域PySetObject數組(可存放80個)中存在空閑對象,則直接分配最後一個對象,然後將資料歸零 2 否則使用PyType_GenericAlloc函數從記憶體池中分配空間。PyType_GenericAlloc函數為python通用的類型分配函 數。
set_new函數執行完畢後,set_init函數將會得到調用。在set_init函數中首先調用set_clear_internal來釋放空間中 原有對象。然後調用set_update_internal來添加對象。由於在frozenset初始化也會調用該函數,所以該函數不會從效率上影響兩種 類型的初始化,此處我們不深入討論該函數。 set_init函數執行完畢後,set初始化結束
(二)frozenset初始化
frozenset_new會對傳入的迭代器做判斷,如果傳入的也是fronzenset對象的話則直接返回該迭代器本身。否則它同樣是調用 make_new_set來為新的集合申請空間,不同的是它會將傳入的迭代器一併傳遞給make_new_set函數。在make_new_set完成如 set中提到的一樣的工作後,它判斷迭代器是否為空白,如果不為空白它就調用set_update_internal來添加對象。
通過上面的分析可以看出在set初始化的過程中,會多調用一次set_clear_internal函數,所以從理論上來說frozenset會比set 略快,但由於該函數的調用與傳入的迭代器的大小無關,且在實際運行中其他因素的影響遠大於該函數的調用,所以我們可以認為set和frozenset的速 度是一樣的。在兩者都能用的情況下,建議使用frozenset,這樣可以避免不小心對資料進行修改。
通過前面我們知道,set初始化時會多調用一次清楚表裡面實際內容的函數,那麼它為什麼要執行這樣的操作呢。以後的文章中我們將會對此進行解釋。