集合类型操作符(所有的集合类型)
联合( | )
联合(union)操作和集合的OR(又称可兼析取(inclusive disjunction))其实是等价的,两个集
合的联合是一个新集合,该集合中的每个元素都至少是其中一个集合的成员,即,属于两个集合其
中 之一的成员。联合符号有一个等价的方法,union().

Edit By Vheavens
 Edit By Vheavens
 >>> s | t
 set(['c', 'b', 'e', 'h', 'k', 'o', 'p', 's'])


交集( & )
你 可以把交集操作比做集合的AND(或合取)操作。两个集合的交集是一个新集合,该集合中的每
个元素同时是两个集合中的成员,即,属于两个集合的成 员。交集符号有一个等价的方法,

intersection().
 >>> s & t
 set(['h', 's', 'o', 'p']


差补/相对补集( � )
两个集合(s 和t)的差补或相对补集是指一个集合C,该集合中的元素,只属于集合s,而不属
于集合t。差符号有一个等价的方法,difference().

>>> s - t
 set(['c', 'e'])


对称差分( ^ )
和其他的布尔集合操作相似,对称差分是集合的XOR(又称"异 或" (exclusive disjunction)).
两个集合(s 和t)的对称差分是指另外一个集合C,该集合中的元素,只能是属于集合s 或者集合t
的成员,不能同时属于两个集合。对称差分有一个等价的方 法,symmetric_difference().

>>> s ^ t
 set(['k', 'b', 'e', 'c'])


混合集合类型操作
上面的示例中,左边的s 是可变集合,而右边的t 是一个不可变集合. 注意上面使用集合操作
运算符 所产生的仍然是可变集合,但是如果左右操作数的顺序反过来,结果就不一样了:

>>> t | s
 frozenset(['c', 'b', 'e', 'h', 'k', 'o', 'p', 's'])
 >>> t ^ s
 frozenset(['c', 'b', 'e', 'k'])
 >>> t - s frozenset(['k', 'b'])


如果左右两个操作 数的类型相同,既都是可变集合或不可变集合, 则所产生的结果类型是相同
的,但如果左右两个操作数的类型不相同(左操作数是set,右操作数是 frozenset,或相反情况),
Edit By Vheavens
Edit By Vheavens
则所产生的结果类型与左 操作数的类型相同,上例中可以证明这一点。还要注意,加号不是集合类
型的运算符:

>>> v = s + t
 Traceback (most recent call last):
 File "<stdin>", line 1, in ?
 TypeError: unsupported operand type(s) for +: 'set' and 'set'
 >>> v = s | t
 >>> v
 set(['c', 'b', 'e', 'h', 'k', 'o', 'p', 's'])
 >>> len(v)
 8
 >>> s < v
 True

 


[Python学习]集合 (sets)模块


sets是 Python 2.3 中新增的,它可以用来处理集合类型的数据。什么是集合?无序、唯一。

 

在这个模块中提供了两个集合类:Set(可变集合)和ImmurableSet(不可变集合)。

 

在我以前写过的一篇Blog中(一个Python小程序:目录比较程 序(一) )有一段代码需要求两个目录中相同文件名的列表,我当时是将两个列表进行排序,然后通过一遍扫描进行求解,还是有一点算法的难度的。如果使用集合类就简单 和清晰多了。代码如下:

 

import filecmp, sys, os
from os.path import walk, isfile, join, basename, normpath, splitext
import sets

 

if __name__ == “__main__”:
     dir1=normpath(sys.argv[1])
     dir2=normpath(sys.argv[2])
     len1=len(dir1)+1
     len2=len(dir2)+1
     files1=[]
     files2=[]
     exts=['.pyc', '.bak', '.ddd', '.png', '.gif', '.jpg']  
 
    def visit(arg, dirname, names, files=files1, length=len1):
         if basename(dirname)!=’CVS’:
             files +=[join(dirname, file)[length:].replace(’//’, ‘/’) 
                 for file in names if isfile(join(dirname, file)) 
                 and splitext(file)[1].lower() not in exts]  
 
    walk(dir1, visit, 0)
1    dirs1 = sets.Set(files1) 
 
    def visit(arg, dirname, names, files=files2, length=len2):
         if basename(dirname)!=’CVS’:
             files +=[join(dirname, file)[length:].replace(’//’, ‘/’) 
                 for file in names if isfile(join(dirname, file))
                 and splitext(file)[1].lower() not in exts]  
 
    walk(dir2, visit, 0)
2    dirs2 = sets.Set(files2)
     
3    common=dirs1 & dirs2
 4    dirs1.difference_update(common)
 5    dirs2.difference_update(common)
 6    files1 = list(dirs1)
 7    files1.sort()
 8    files2 = list(dirs2)
 9    files2.sort()
 10    commons=list(common)
 11    commons.sort()
     
 
    print ‘%s vs %s’ % (dir1, dir2)
     print ’state filename’
     print ‘—– ——————————’
     for f in files1:
         print ‘  >   %s’ % f
     for f in files2:
         print ‘  <   %s’ % f
     for f in match:
         print ‘  =   %s’ % f
     for f in mismatch:
         print ‘ !=   %s’ % f

 

第1行:生成dirs1集合
第2行:生成dirs2集合
第3行:求dirs1和dirs2的交集,即求两个目录中相同文件名的集合
第 4行:求只在dirs1中存在的文件名,带有_update的方法会更新原集合对象,而不带的则会生成新的集合
第5行:同第4行,求只在 dirs2中存在的文件名
第6-7行:将集合转化为列表,并排序
第8-9行:同第6-7行
第10-11行:同第6-7行
第 12行:比较两个目录中同名的文件

 

不过集合是无序的,因此当你需要按顺序输出元素时则需要先将其转化为有序的列表或元组,再进行输出。这一点有些麻烦。

 

生成一个列表可以从list或tuple甚至dictionary直接生成。如果直接使用dictionary,则会取出键值作为集合的元素,如:

 

>>> a={1:’a', 2:’b'}
 >>> b=sets.Set(a)
 >>> b
 Set([1, 2])

 

如果想将字典的值生成集合怎么办呢?

 

>>> b=sets.Set(a.values())
 >>> b
 Set(['a', 'b'])

 

更详细的关于集合类的使用请查阅 Python 2.3 的文档。