专栏名称: Python开发者
人生苦短,我用 Python。伯乐在线旗下账号「Python开发者」分享 Python 相关的技术文章、工具资源、精选课程、热点资讯等。
目录
相关文章推荐
51好读  ›  专栏  ›  Python开发者

Python 集合 set 和 frozenset 的内建方法详解

Python开发者  · 公众号  · Python  · 2017-05-18 19:51

主要观点总结

本文介绍了Python中集合(set)的相关概念和用法,包括可变集合(set)、不可变集合(frozenset)的基本操作以及集合之间的关系等。

关键观点总结

关键观点1: 集合的基本概念

集合是一种无序的、不重复的元素集,类似于数学中的集合概念,可以进行交、并、差、补等逻辑运算。

关键观点2: set和frozenset的区别

set是一种可变集合,可以进行添加、删除、修改等操作;而frozenset是一种不可变集合,一旦创建后无法更改。

关键观点3: 集合的基本操作

包括创建集合、增加元素、删除元素、合并集合、求交集、求并集、求差集等。

关键观点4: 集合间的关系

包括相等、包含、被包含等关系,以及使用isdisjoint()、issuperset()、issubset()等方法来判断集合之间的关系。

关键观点5: 集合的数据类型转换

集合可以转换为列表、元组、字符串等序列类型。


正文

请到「今天看啥」查看全文


(点击 上方蓝字 ,快速关注我们)


来源:JmilkFan

blog.csdn.net/Jmilk/article/details/49819843

如有好文章投稿,请点击 → 这里了解详情


前言


集合是一种组合型的数据类型,分为可变的set和不可变的frozenset。


软件环境


  • 系统

    • UbuntuKylin 14.04

  • 软件

    • Python 2.7.3

    • IPython 4.0.0

可变集合Set


集合set是一种无序的、唯一的的元素集,与数学中集合的概念类似,可对其进行交、并、差、补等逻辑运算。不支持索引、切片等序列操作,但仍支持成员关系运算符in-not in、推导式等操作。在特定的场合中可以体现出非常优秀的执行效率。


set()函数创建集合


set(iterable) -> new set object


其中iterable可以是List、Tuple、Dictionary。但是为dict时,只会获取提Key作为set的元素。


n [ 12 ] : s = set ([ 1 , 2 , 3 ])

In [ 13 ] : s

Out [ 13 ] : { 1 , 2 , 3 }

In [ 14 ] : type ( s )

Out [ 14 ] : set

In [ 141 ] : s2 = set ( 'jmilk' )

In [ 142 ] : s2

Out [ 142 ] : { 'i' , 'j' , 'k' , 'l' , 'm' }


注意:set()函数只能接受迭代器(String、Tuple、List、Dict、set)作为参数。


In [ 180 ] : s1 = set ( 1 )

---------------------------------------------------------------------------

TypeError Traceback ( most recent call last )

ipython - input - 180 - 8804a520da97 > in module > ()

----> 1 s1 = set ( 1 )

TypeError : 'int' object is not iterable


传递一个非迭代器参数时会报错。


创建空集合


set() -> new empty set object


通过上面的例子,可见set类型数据和dict类型一样也是使用{}来标识,但是需要注意的是:dict类型可以使用dic = {}来创建一个空字典,set类型却不能,只能通过s = set()来创建。


In [ 15 ] : s = set ()

In [ 16 ] : s

Out [ 16 ] : set ()

In [ 17 ] : d = {}

In [ 18 ] : d

Out [ 18 ] : {}

In [ 20 ] : type ( s ), type ( d )

Out [ 20 ] : ( set , dict )


注意:因为set()是一个可变的集合,其元素的数量是不固定的,所以有add()、remove()方法。但也因为其可变性所以set()类型的对象没有散列值(哈希值),同时也不能作为dict对象的key和其他set对象的元素。


哈希值: 将长度不一的输入数据源,通过算法转换为长度一致的数据输出,以此来提高查找速度。


MD5: 对文件或者数据源(字符串、数值)进行计算后得到一个固定的值,用来验证文件或数据源是否被篡改。一般用于文件的数字签名。


集合元素的唯一性


无论是set还是frozenset中的元素都是唯一的,会自动合并重叠元素。


In [ 17 ] : li = [ 1 , 2 , 3 , 1 , 1 , 2 , 'a' , 'b' , 'a' ]

In [ 18 ] : s1 = set ( li )

In [ 19 ] : s2 = frozenset ( li )

In [ 20 ] : s1 , s2

Out [ 20 ] : ({ 1 , 2 , 3 , 'a' , 'b' }, frozenset ({ 1 , 2 , 3 , 'a' , 'b' }))


集合推导式


由一个迭代器推倒出一个新的集合。


In [ 175 ] : set ( x ** 2 for x in range ( 1 , 6 ) if x 4 )

Out [ 175 ] : { 1 , 4 , 9 }


set类型对象的内置方法


add()增加一个元素


add(…)

Add an element to a set.

This has no effect if the element is already present.


增加一个元素到set对象中,如果这个元素已经存在,则没有效果。


In [ 41 ] : s1 = set ( range ( 10 ))

In [ 42 ] : s1

Out [ 42 ] : { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 }

In [ 43 ] : s1 . add ( 10 )

In [ 44 ] : s1

Out [ 44 ] : { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 }


remove()删除一个元素


remove(…)

Remove an element from a set; it must be a member.

If the element is not a member, raise a KeyError.


指定删除set对象中的一个元素,如果集合中没有这个元素,则返回一个错误。


In [ 47 ] : s1

Out [ 47 ] : { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 }

In [ 48 ] : s1 . remove ( 0 )

In [ 49 ] : s1

Out [ 49 ] : { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 }


一次只能删除i个元素。


pop()随机删除并返回一个元素


pop(…)

Remove and return an arbitrary set element.

Raises KeyError if the set is empty.


随机删除并返回一个集合中的元素,若集合为空,则返回一个错误。


In [ 65 ] : s2 = set ([ 'j' , 'm' , 'i' , 'l' , 'k' ])

In [ 66 ] : s2 . pop ()

Out [ 66 ] : 'i'

In [ 67 ] : s2 . pop ()

Out [ 67 ] : 'k'


discard()删除一个元素


discard(…)

Remove an element from a set if it is a member.

If the element is not a member, do nothing.


指定删除集合中的一个元素,若没有这个元素,则do nothing。


In [ 90 ] : s1

Out [ 90 ] : { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 }

In [ 91 ] : s1 . discard ( 1 )

In [ 92 ] : s1

Out [ 92 ] : { 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 }

In [ 93 ] : s1 . discard ( 'abc' )

In [ 94 ] : s1

Out [ 94 ] : { 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 }


clear()


clear(…)

Remove all elements from this set.


清空一个集合中的所有元素


In [ 94 ] : s1

Out [ 94 ] : { 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 }

In [ 95 ] : s1 . clear ()

In [ 96 ] : s1

Out [ 96 ] : set ()


注意:上面列出的函数都是可变类型set对象独有的函数,除此之外还有一些set和frozenset共有的内置函数,我们后面再介绍。


不可变集合Frozenset


frozenset冻结集合,即不可变集合。frozenset的元素是固定的,一旦创建后就无法增加、删除和修改。其最大的优点是使用hash算法实现,所以执行速度快,而且frozenset可以作为dict字典的Key,也可以成为其他集合的元素。


frozenset()创建一个frozenset集合


frozenset(object)

frozenset() -> empty frozenset object

frozenset(iterable) -> frozenset object

Build an immutable unordered collection of unique elements.


创建的固定的无序集合


In [ 108 ] : f1 = frozenset () #空的frozenset集合

In [ 109 ] : f2 = frozenset ([ 1 , 2 , 3 , 'JMilk' ])

In [ 110 ] : f1 , f2

Out [ 110 ] : ( frozenset (), frozenset ({ 1 , 2 , 3 , 'JMilk' }))


set能够与frozenset作比较


In [ 4 ] : s1 = set ([ 1 , 2 , 3 ])

In [ 5 ] : s2 = frozenset ([ 1 , 2 , 3 ])

In [ 6 ] : s1 == s2

Out [ 6 ] : True


set和frozenset的混合运算


两种类型集合之间的混合运算会返回第一个操作元素的类型。


In [ 12 ] : s1 = set ([ 1 , 2 , 3 ])

In [ 13 ] : s2 = frozenset ([ 2 , 3 , 4 ])

In [ 14 ] : s3 = s1 | s2

In [ 15 ] : s3 , type ( s3 )

Out [ 15 ] : ({ 1 , 2 , 3 , 4 }, set )


frozenset集合作为dic的key


In [ 138 ] : f = frozenset ([ 'name' ])

In [ 139 ] : dic = { f : 'Jmilk' }

In [ 140 ] : dic

Out [ 140 ] : { frozenset ({ 'name' }) : 'Jmilk' }


set集合不可以作为Dictionary的Key:


In [ 144 ] : s1 = set ([ 'JMilk' ])

In [ 145 ] : dic = { s1 : 'name' }

---------------------------------------------------------------------------

TypeError Traceback ( most recent call last )

ipython - input - 145 - a2aec7bb3b32 > in module > ()

----> 1 dic = { s1 : 'name' }

TypeError : unhashable type : 'set' #不具有hash


set、frozenset共有的内建函数


set与frozenset类型的集合都支持集合之间的比较、交、并、差操作,类似数据的集合关系比较。但是需要注意的是:因为frozenset是不可变集合,所以下列函数中带有’_update’关键字的函数,frozenset都不可以调用。


NOTE: 带有 _update 的函数,使用原位操作的方法实现,拥有更低的资源消耗。但是这样的话,函数是没有返回值的,即不能将结果赋值给一个新的变量。


intersection()、intersection_update()求交集


intersection(…)

Return the intersection of two or more sets as a new set.


返回一个由若干个集合经过交集运算后得到的新交集,可以传入多个迭代器类型的参数。即可以传递Tuple、List、、String、Dictionary、Set等类型参数。


集合之间求交集


In [ 59 ] : s1

Out [ 59 ] : { 1 , 2 , 3 , 'a' , 'b' }

In [ 60 ] : s2

Out [ 60 ] : { 3 , 4 , 5 , 'b' , 'c' , 'd' }

In [ 61 ] : s3 = set ([ 1 , 3 , 8 , 9 , 10 , 'd''e' , 'f' ])

In [ 62 ] : s4 = s1 . intersection ( s2 , s3 )

In [ 63 ] : s4

Out [ 63 ] : { 3 }


注意:也可以使用逻辑与运算符 ‘&’


In [ 28 ] : s3 = s1 & s2

In [ 29 ] : s3

Out [ 29 ] : { 3 , 'b' }


集合和列表求交集


In [ 64 ] : li

Out [ 64 ] : [ 1 , 2 , 3 , 1 , 1 , 2 , 'a' , 'b' , 'a' ]

In [ 65 ] : s4 = s1 . intersection ( li )

In [ 66 ] : s4

Out [ 66 ] : { 1 , 2 , 3 , 'a' , 'b' }


集合和元组求交集


In [ 67 ] : tup = ( 2 , 'a' , 'c' )

In [ 68 ] : s4 = s1 . intersection ( tup )

In [ 69 ] : s4

Out [ 69 ] : { 2 , 'a' }


集合和字符串求交集


注意:只能以String中的字符进行相交运算,不能与String的数字做运算。


In [ 70 ] : str = '123abc'

In [ 71 ] : s4 = s1 . intersection ( str )

In [ 72 ] : s4

Out [ 72 ] : { 'a' , 'b' }

In [ 79 ] : s1

Out [ 79 ] : { 1 , 2 , 3 , 'a' , 'b' }


集合和字典求交集


注意:只能与字典中的Key进行相交运算。


In [ 79 ] : s1

Out [ 79 ] : { 1 , 2 , 3 , 'a' , 'b' }

In [ 80 ] : dic = { 1 : 'name' , 2 : 'age' }

In [ 81 ] : s4 = s1 . intersection ( dic )

In [ 82 ] : s4

Out [ 82 ] : { 1 , 2 }


intersection()与intersection_update()的区别


intersection_update(…)

Update a set with the intersection of itself and another.

更新一个经过相交后的集合给自己。


注意:当我们希望将两个对象相交后的结果更新给其中一个操作对象时,建议使用intersection_update()函数,这个函数使用原位操作的方法实现,拥有更低的资源消耗。但是intersection_update()函数是没有返回值的,即不能将结果赋值给一个新的变量。


In [ 94 ] : s1

Out [ 94 ] : { 1 , 2 , 3 , 'a' , 'b' }

In [ 95 ] : s2

Out [ 95 ] : { 3 , 4 , 5 , 'b' , 'c' , 'd' }

In [ 96 ] : s1 . intersection_update ( s2 )

In [ 97 ] : s1

Out [ 97 ] : { 3 , 'b' }


union()、update()求并集


与intersection()一样,可以传递不同的迭代器类型参数。


union() 返回并集


union(…)

Return the union of sets as a new set.


In [ 108 ] : s4

Out [ 108 ] : { 1 , 2 , 3 , 4 , 5 , 8 , 9 , 10 , 'a' , 'b' , 'c' , 'd' , 'de' , 'f' }


注意:可以使用逻辑或运算符 ‘|’


In [ 109 ] : s4 = s1 | s2 | s3

In [ 110 ] : s4

Out [ 110 ] : { 1 , 2 , 3 , 4 , 5 , 8 , 9 , 10 , 'a' , 'b' , 'c' , 'd' , 'de' , 'f' }


update()更新并集


update(…)

Update a set with the union of itself and others.

update()方法没有返回值。


In [ 111 ] : s1 . update ( s2 , s3 )

In [ 112 ] : s1

Out [ 112 ] : { 1 , 2 , 3 , 4 , 5 , 8 , 9 , 10 , 'a' , 'b' , 'c' , 'd' , 'de' , 'f' }


difference()、difference_update()求差


difference()


difference(…)

Return the difference of two or more sets as a new set.


返回由一个集合中不存在于其他若干个集合的元素组成的新集合。


In [ 122 ] : s1

Out [ 122 ] : { 1 , 2 , 3 , 'a' , 'b' }

In [ 123 ] : s2

Out [ 123 ] : { 3 , 4 , 5 , 'b' , 'c' , 'd' }

In [ 124 ] : s3 = s1 . difference ( s2 )

In [ 125 ] : s3

Out [ 125 ] : { 1 , 2 , 'a' }


注意:可以使用算术运算符减 ‘-‘


In [ 126 ] : s3 = s1 - s2

In [ 127 ] : s3

Out [ 127 ] : { 1 , 2 , 'a' }


difference_update()


difference_update(…)

Remove all elements of another set from this set.


更新原来集合。


In [ 130 ] : s1 . difference_update ( s2 )

In [ 131 ] : s1

Out [ 131 ] : { 1 , 2 , 'a' }


symmetric_difference()、symmetric_difference_update()求集合彼此之差的并集


symmetric_difference()


symmetric_difference(…)

Return the symmetric difference of two sets as a new set.


即返回(set1 – set2)|(set2 – set1)的结果


In [ 138 ] : s1

Out [ 138 ] : { 1 , 2 , 3 , 'a' , 'b' }

In [ 139 ] : s2

Out [ 139 ] : { 3 , 4 , 5 , 'b' , 'c' , 'd' }

In [ 140 ] : s3 = s1 . symmetric_difference ( s2 )

In [ 141 ] : s3

Out [ 141 ] : { 1 , 2 , 4 , 5 , 'a' , 'c' , 'd' }


等效于:


In [ 147 ] : s1 - s2

Out [ 147 ] : { 1 , 2 , 'a' }

In [ 148 ] : s2 - s1

Out [ 148 ] : { 4 , 5 , 'c' , 'd' }

In [ 144 ] : s3 = ( s1 - s2 ) | ( s2 - s1 )

In [ 145 ] : s3

Out [ 145 ] : { 1 , 2 , 4 , 5 , 'a' , 'c' , 'd' }


注意:可以使用^来代替


In [ 142 ] : s3 = s1 ^ s2

In [ 143 ] : s3

Out [ 143 ] : { 1 , 2 , 4 , 5 , 'a' , 'c' , 'd' }


symmetric_difference_update()


symmetric_difference_update(…)

Update a set with the symmetric difference of itself and another.


In [ 150 ] : s1 . symmetric_difference_update ( s2 )

In [ 151 ] : s1

Out [ 151 ] : { 1 , 2 , 4 , 5 , 'a' , 'c' , 'd' }


集合间的关系


相等:只有每一个一个set都互相是另一个set的子集时,这两个set才相等。

小于(set1包含于set2):只有当第一个set1是另一个set2的子集,别且两个set不相等时,第一个set1小于第二个set2。

大于(set1包含set2):只有第一个set1是第二个set2的超集、并且两者不相等时,第一个set2大于第二个set2。


isdisjoint()两个集合不相交


isdisjoint(…)

Return True if two sets have a null intersection.


即set1 & set2 == set() 时,为True


In [ 155 ] : s1

Out [ 155 ] : { 1 , 2 , 4 , 5 , 'a' , 'c' , 'd' }

In [ 156 ] : s2

Out [ 156 ] : { 3 , 4 , 5 , 'b' , 'c' , 'd' }

In [ 158 ] : ( s1 - s2 ) & s2 == set ()

Out [ 158 ] : True

In [ 159 ] : s2 . isdisjoint ( s1 - s2 )

Out [ 159 ] : True


issuperset()一个集合包含另一个集合


issuperset(…)

Report whether this set contains another set.


In [ 169 ] : s1

Out [ 169 ] : { 0 , 1 , 2 }

In [ 170 ] : s2

Out [ 170 ] : { 0 , 1 , 2 , 3 , 4 }

In [ 172 ] : s2 . issuperset ( s1 )

Out [ 172 ] : True


s2大于s1


issubset()一个集合包含于另一个集合


issubset(…)

Report whether another set contains this set.


In [ 169 ] : s1

Out [ 169 ] : { 0 , 1 , 2 }

In [ 170 ] : s2

Out [ 170 ] : { 0 , 1 , 2 , 3 , 4 }

In [ 171 ] : s1 . issubset ( s2 )

Out [ 171 ] : True


s1被s2包含


集合的数据类型转换


主要转换为序列类型。


In [ 1 ] : set1 = set ( range ( 5 ))

In [ 2 ] : li = list ( set1 )

In [ 3 ] : tup = tuple ( set1 )

In [ 4 ] : string = str ( set1 )

In [ 5 ] : li , tup , string

Out [ 5 ] : ([ 0 , 1 , 2 , 3 , 4 ], ( 0 , 1 , 2 , 3 , 4 ), 'set([0, 1, 2, 3, 4])' )


最后


集合是一个非常有意思的数据结构,他或许不被经常使用,但是在比较严格的执行环境下,集合是一个非常好的选择。


看完本文有收获?请转 发分享给更多人

关注「Python开发者」,提升Python技能







请到「今天看啥」查看全文