Python中的set类型和数学中的集合很相似,支持联合( union或| )、交( intersection 或& )、差( difference或- )和 对称差集( symmetric_difference或^ )等运算。由于python set中元素的不重复性,因此set可用于去掉重复元素。
a = set('abc') b = set('bcd') >>> print a&b,a.intersection(b) set(['c', 'b']) set(['c', 'b']) >>> print a|b, a.union(b) set(['a', 'c', 'b', 'd']) set(['a', 'c', 'b', 'd']) >>> print a-b, a.difference(b) set(['a']) set(['a']) >>> print a^b, a.symmetric_difference(b) set(['a', 'd']) set(['a', 'd'])
来看看去重:
>>> lst = [1,2,2,3,3] >>> list(set(lst)) [1, 2, 3]
set可以作用于iterable对象创建新的set对象,但是iterable对象的每个元素必须是可hash的。和dict的key一样,必须可hash。可使用内建函数hash判断对象是否可hash。
>>> hash(())#可hash 3527539 >>> hash([])#不可hash Traceback (most recent call last): File "<pyshell#95>", line 1, in <module> hash([]) TypeError: unhashable type: 'list' >>> hash({})#不可hash Traceback (most recent call last): File "<pyshell#96>", line 1, in <module> hash({}) TypeError: unhashable type: 'dict' >>> hash(([1,2],3))#不可hash Traceback (most recent call last): File "<pyshell#97>", line 1, in <module> hash(([1,2],3)) TypeError: unhashable type: 'list' >>> hash((1,2))#可hash 1299869600
对于元素是不可hash的可迭代对象,使用set去重复前,要先将对象的元素改成可hash。
>>> a = [[1,2], [3,4], [1,2]] >>> print list(set(a)) Traceback (most recent call last): File "<pyshell#100>", line 1, in <module> print list(set(a)) TypeError: unhashable type: 'list' >>> print list(set(tuple(it) for it in a)) [(1, 2), (3, 4)]
在python中使用集合是比较高效的,来看个例子。求两个list的交集,测试性能。
root@(none):~# python -m timeit -n 10000 "range1=range(1, 200);range2=range(300);[x for x in range1 if x in range2]" 10000 loops, best of 3: 220 usec per loop root@(none):~# python -m timeit -n 10000 "range1=range(100, 101);range2=range(300);set(range1).intersection(range2)" 10000 loops, best of 3: 6.07 usec per loop
第一种,遍历list,第二种,使用集合操作,显然使用集合的性能很高,当然第一种也可以优化。
python -m module,在sys.path中找到module模块,然后执行改py文件。-n 10000 是timeit.py的参数。