Python 中有一个数据结构叫 set,set 和 dict 类似,也是一组 key 的集合,但不存储 value。
由于 key 不能重复,所以在 set 中没有重复的成员。
set 的定义需要提供一个 list 作为输入集合。
myset = set([1, False, "老鸟python"]) print(myset)
set 中成员的特性和 dict 成员的 key 一样,必须是可以 hash 的。
myset = set([1, [1, 2], "老鸟python"]) # 错误,成员 [1, 2] 不可 hash print(myset)
set 中成员重复的话,只有一个起作用,这和 dict 的 key 一样。
myset = set([1, 1, "老鸟python"]) print(myset # set([1, '老鸟python']))
set 是无序的,不可以通过下标访问。
myset = set([1, 1, "老鸟python"]) print(myset[0]) # 错误
set 内部的数据结构是 hash 表,所以定义完成后,set 内部成员的存储顺序不一定是初始化的顺序。
myset = set(["a", "b", "c"]) print(myset # set(['a', 'c', 'b']))
通过 set 提供的 add 函数可以添加成员到 set 中。
myset = set(["a", "b", "c"]) myset.add("d") print(myset)
通过 set 提供的 remove 函数可以删除成员,但如果删除的成员不存在,python 会抛出异常;set 还有一个 discard 函数也可以删除成员,并且会自动处理异常。
myset = set(["a", "b", "c"]) myset.remove("b") print(myset) myset.remove("d") # 抛出异常 myset.discard("d") # 不做任何处理
set 的 pop 函数从集合中移除成员,并返回移除的成员,pop 函数删除成员是从内存中第一个成员依次删除。注意:Python解释器版本不同,分配内存的顺序不一定相同,也有的解释器每次执行时分配的内存分配的顺序也不同。
myset = set(["a", "b", "c"]) print(myset) # 假定内存顺序为:set(['a', 'c', 'b']) myset.pop() print(myset) # set(['c', 'b']) myset.pop() print(myset) # set(['b'])
注意事项:set 是无序集合,所以不能通过下标访问 set 成员,set 里面的成员和 dict 的 key 一样,而无 dict 的 value,所以 set 的成员无法通过 set[] 来获取成员。
set 可以看成数学意义上的无序和无重复元素的集合,因此,两个 set 可以做数学意义上的交集,并集等操作。
myset_one = set([1, 2, 3, 4]) myset_two = set([2, 4, 6, 8]) myset_three = myset_one & myset_two myset_four = myset_one | myset_two print(myset_three # set([2, 4])) print(myset_four # set([1, 2, 3, 4, 6, 8]))
set 的定义和函数使用。
set 进行交集和并集运算。
运行一下程序,看看结果,想想为什么?
myset_one = set([1, True, None, False, 0]) print(myset_one)
myset_one = set([1, True, None, False, 0])
print(myset_one)
运行结果:
{False, 1, None}
练习:tuple虽然是不变对象,但试试把(1, 2, 3)和(1, [2, 3])放入dict或set中,并解释结果。
代码:
d1={(1,2,3)}
print(d1)#输出{(1,2,3)}
d2={(1,[2,3])}
print(d2)#报错:unhashable type:'list'
解释:dict的key是不可变对象,要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key,即[2,3]是一个list类型,可变的,则不能作为key。
对于集合,如果要创建一个空集合,不能使用s={}来创建空集合,因为这样创建的是一个dict。创建集合可以使用s={xx,xx,xx},也可以使用set([xx,xx,xx]),但创建空集合只能使用s=set()
这个set里的pop移除是随机的吗
set可以直接用{}定义
s = set([1,2,3])
等价于
s = {1,2,3}
s = set([1, 2, 3]) #不会报错 s = set((1, 2, 3)) #为什么会报错呢
你弄成中文的括号了,改成英文的就好了
s = set((1, 2, 3)) print(s) # set([1, 2, 3]) print type(s) # <type 'set'>
有两点疑问
1.刚开始用set时,教程里说是要创建一个set,需要提供一个list作为输入集合:
>>> s = set([1, 2, 3]) >>> s {1, 2, 3}
最后又说set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”。试试把list放入set,看看是否会报错。
这不是互相矛盾吗?
2.为什么s = set([1,2,3])
不报错,而s = set((1,[2,3])
报错,明明都是变化的
楼下的相同问题的解答我是属实没看懂,有搞明白的老哥可以给解释一下吗,感激不尽!!
你可以将s = set([1, 2, 3]) 中的 [1,2,3] 理解为set这个类型对其包含的数据的一个形式上的要求,这里并不是list作为set的key,而是list中的元素作为了set的key。
换句话说,无论你准备把任何东西装入set,它都必须先是一个list(或者tuple)的形式,甚至是空集,也得是 [ ] 。
再来看第二个,s = set((1,[2,3]))的中,先进行赋值
list1 = [2,3]
则,这时候的s变换为
s = set((1, list1))
看到这里你明白了吗?这是在想将一个tuple = (1, list1) 装入s这个set。这个tuple中有两个元素,一个是1,一个是list1,因为list1可变(不可hash),所以不能存入s这个set中,也就会报错了。
赞一个
解释的非常棒!!!
set最多接收一个参数
{False, 1, None}