Python语言中有两类比较特殊的数据类型,字典dict和集合set。
1、字典和集合都是用大括号表示,先看两个例子:
>>> num1 = {}
>>> type(num1)
<class 'dict'>
>>>
>>> num2= {1, 2, 3, 4, 5}
>>> type(num2)
<class 'set'>
2、字典的表示形式是键值对(key-value),而集合中的元素是唯一的:
>>> dict1 = {1 : 'one', 2 : 'two', 3 : 'three'}
>>> type(dict1)
<class 'dict'>
>>> dict1
{1: 'one', 2: 'two', 3: 'three'}
>>>
>>> set1 = {1, 2, 3, 4, 5, 4, 3, 2, 1}
>>> type(set1)
<class 'set'>
>>> set1
{1, 2, 3, 4, 5}
3、字典的构造函数:
字典的构造函数为dict,分别有三种形式:dict()、dict(**args)、dict(mapping)
>>> #dict()返回一个空的字典
>>> d1 = dict()
>>> d1
{}
>>>
>>> #dict(**args)
>>> d2 = dict(a = 1, b = 2, c = 3)
>>> d2
{'a': 1, 'b': 2, 'c': 3}
>>>
>>> #dict(mapping)
>>> d3 = dict((('a', 1), ('b', 2), ('c', 3), ('d', 4)))
>>> d3
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
>>>
4、内置方法
1)字典的内置方法有fromkeys()、keys()、values()、items()、get()、clear()、copy()、pop()、popitem()、update()、setdefault()。
>>> dir(dict)
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
>>>
>>> #fromkeys()
>>> dict1 = {}
>>> dict1.fromkeys((1, 2, 3))
{1: None, 2: None, 3: None}
>>> dict1.fromkeys((1, 2, 3), 'Number')
{1: 'Number', 2: 'Number', 3: 'Number'}
>>> dict1.fromkeys((1, 2, 3), ('one', 'two', 'three'))
{1: ('one', 'two', 'three'), 2: ('one', 'two', 'three'), 3: ('one', 'two', 'three')}
>>>
>>> #keys()、values()、items()
>>> dict2 = dict.fromkeys(range(10), 'Hello')
>>> dict2
{0: 'Hello', 1: 'Hello', 2: 'Hello', 3: 'Hello', 4: 'Hello', 5: 'Hello', 6: 'Hello', 7: 'Hello', 8: 'Hello', 9: 'Hello'}
>>> for eachkey in dict2.keys():
print(eachkey, end = ' ')
0 1 2 3 4 5 6 7 8 9
>>> for eachvalue in dict2.values():
print(eachvalue, end = ' ')
Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello
>>>
>>> for eachitem in dict2.items():
print(eachitem, end = ' ')
(0, 'Hello') (1, 'Hello') (2, 'Hello') (3, 'Hello') (4, 'Hello') (5, 'Hello') (6, 'Hello') (7, 'Hello') (8, 'Hello') (9, 'Hello')
>>>
>>> #get()
>>> dict2.get(10)
>>> print(dict2.get(10))
None
>>> dict2.get(10, '该键值不存在!')
'该键值不存在!'
>>> dict2.get(9, '该键值不存在!')
'Hello'
>>>
>>> #clear()
>>> dict2
{0: 'Hello', 1: 'Hello', 2: 'Hello', 3: 'Hello', 4: 'Hello', 5: 'Hello', 6: 'Hello', 7: 'Hello', 8: 'Hello', 9: 'Hello'}
>>> dict2.clear()
>>> dict2
{}
>>> a = {1 : 'one'}
>>> b = a
>>> a
{1: 'one'}
>>> b
{1: 'one'}
>>> a.clear()
>>> a
{}
>>> b
{}
>>>
>>> #copy()浅拷贝
>>> #浅拷贝与赋值的区别
>>> dict1 = {1 : 'one', 2 : 'two', 3 : 'three'}
>>> dict2 = dict1.copy()
>>> dict3 = dict1
>>> dict1
{1: 'one', 2: 'two', 3: 'three'}
>>> dict2
{1: 'one', 2: 'two', 3: 'three'}
>>> dict3
{1: 'one', 2: 'two', 3: 'three'}
>>> id(dict1)
54130440
>>> id(dict2)
54130760
>>> id(dict3)
54130440
>>> dict3[4] = 'four'
>>> dict1
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> dict2
{1: 'one', 2: 'two', 3: 'three'}
>>> dict3
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>>
>>> #pop()、popitem()
>>> dict1
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> dict1.pop(2)
'two'
>>> dict1
{1: 'one', 3: 'three', 4: 'four'}
>>> dict1.popitem()
(1, 'one')
>>> dict1
{3: 'three', 4: 'four'}
>>> dict2
{1: 'one', 2: 'two', 3: 'three'}
>>> dict.popitem(dict2)
(1, 'one')
>>> dict2
{2: 'two', 3: 'three'}
>>>
>>> #update()
>>> dict1 = {1: 'one', 2: 'two'}
>>> dict2 = {3: 'three'}
>>> dict3 = {3: '333', 4: '444'}
>>> dict1.update(dict2)
>>> dict1
{1: 'one', 2: 'two', 3: 'three'}
>>> dict1.update(dict3)
>>> dict1
{1: 'one', 2: 'two', 3: '333', 4: '444'}
>>>
>>> #setdefault()与get()方法类型,会返回指定键对于的值,不同的是,如果该键不存在,则setdefault方法会在字典中添加该键值对
>>> dict1 = {}
>>> dict1.setdefault(1)
>>> dict1
{1: None}
>>> dict1.setdefault(2, 'two')
'two'
>>> dict1
{1: None, 2: 'two'}
>>> dict1.setdefault(1, 'one')
>>> dict1
{1: None, 2: 'two'}
2)集合的内置方法有add()、remove()、pop()、discard()、clear()、issubset()、issuperset()、union()、difference()、symmetric_difference()、isdisjoint()和copy()——浅拷贝
>>> dir(set)
['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
>>>
>>>#add()
>>> set1 = {0, 1, 2, 3, 4, 5}
>>> set1.add(0)
>>> set1
{0, 1, 2, 3, 4, 5}
>>> set1.add(6)
>>> set1
{0, 1, 2, 3, 4, 5, 6}
>>>
>>>#remove(),删除不存在的元素,抛出异常KeyError
>>> set1
{0, 1, 2, 3, 4, 5, 6}
>>> set1.remove(0)
>>> set1
{1, 2, 3, 4, 5, 6}
>>> set1.remove(0)
Traceback (most recent call last):
File "<pyshell#285>", line 1, in <module>
set1.remove(0)
KeyError: 0
>>>
>>> #pop()随机删除并返回一个集合中的元素,若集合为空,抛出异常
>>> set2 = {1, 2}
>>> set2.pop()
1
>>> set2
{2}
>>> set2.pop()
2
>>> set2
set()
>>> set2.pop()
Traceback (most recent call last):
File "<pyshell#293>", line 1, in <module>
set2.pop()
KeyError: 'pop from an empty set'
>>>
>>> #discard()删除一个元素且不返回,与remove()不同的是,如果该元素不存在,不会抛出异常,do nothing
>>> set1
{1, 2, 3, 4, 5, 6}
>>> set1.discard(1)
>>> set1
{2, 3, 4, 5, 6}
>>> set1.discard(1)
>>> set1
{2, 3, 4, 5, 6}
>>>
>>> #clear()
>>> set1
{2, 3, 4, 5, 6}
>>> set1.clear()
>>> set1
set()
>>> #issubset()、issuperset()超集和子集
>>> s1 = {1, 2, 3, 4}
>>> s2 = {1, 2, 3}
>>> s1.issubset(s2)
False
>>> s1.issuperset(s2)
True
>>> s2.issubset(s1)
True
>>> s2.issuperset(s1)
False
>>>
>>> #union()返回一个新集合,该集合是2个集合的并集
>>> s1 = {1, 2, 3, 4, 7, 8}
>>> s2 = {2 ,4, 6, 8, 10, 12}
>>> s1.union(s2)
{1, 2, 3, 4, 6, 7, 8, 10, 12}
>>> s1
{1, 2, 3, 4, 7, 8}
>>> s2
{2, 4, 6, 8, 10, 12}
>>>
>>> #intersection()返回一个新集合,该集合是2个集合的交集
>>> s1
{1, 2, 3, 4, 7, 8}
>>> s2
{2, 4, 6, 8, 10, 12}
>>> s1.intersection(s2)
{8, 2, 4}
>>> s1
{1, 2, 3, 4, 7, 8}
>>> s2
{2, 4, 6, 8, 10, 12}
>>>
>>> #s1.difference(s2)返回一个新集合,该集合元素是s1的成员,但不是s2的成员
>>> s1
{1, 2, 3, 4, 7, 8}
>>> s2
{2, 4, 6, 8, 10, 12}
>>> s1.difference(s2)
{1, 3, 7}
>>>
>>>#s1.symmetric_difference(s2)返回一个新集合,该集合元素是s1或s2的成员,但不同时属于s1和s2
>>> s1
{1, 2, 3, 4, 7, 8}
>>> s2
{2, 4, 6, 8, 10, 12}
>>> s1.symmetric_difference(s2)
{1, 3, 6, 7, 10, 12}
>>>
>>>#isdisjoint()判断2个集合是否是不想交集,即交集为空
>>>s1 = {1, 2, 3}
>>>s2 = {1, 2, 4}
>>>s3 = {4, 5, 6}
>>>s1.isdisjoint(s2)
False
>>>s1.isdisjoint(s3)
True
5、不可变集合Frozenset
Frozenser从字面意义上来看,翻译成“冻结的集合”,也就是不可变集合。frozenset的元素是固定的,一旦创建后就无法增加、删除和修改。其最大的优点是使用hash算法实现,执行速度快。而且frozenset可以作为dict字典的Key,也可以作为其他集合的元素。
>>> set1 = frozenset([1, 2, 3])
>>> set1
frozenset({1, 2, 3})
>>> set1.add(4)
Traceback (most recent call last):
File "<pyshell#372>", line 1, in <module>
set1.add(4)
AttributeError: 'frozenset' object has no attribute 'add'
>>> set1.remove(1)
Traceback (most recent call last):
File "<pyshell#373>", line 1, in <module>
set1.remove(1)
AttributeError: 'frozenset' object has no attribute 'remove'
>>> set1.discard(1)
Traceback (most recent call last):
File "<pyshell#374>", line 1, in <module>
set1.discard(1)
AttributeError: 'frozenset' object has no attribute 'discard'
>>>
6、difference_update、intersection_update、symmetric_difference_update与difference、intersection、symmetric_difference的区别
我们可以知道update()这个内置函数,是对原集合的更新,那么上述三个函数实际上也是对原集合的更新,及将difference、intersection、symmetric_difference的结果更新到原集合,如下:
>>> s1 = { 1, 2, 3, 4, 5, 8, 10}
>>> s2 = { 2, 4, 6, 8, 10, 12}
>>> s1.difference(s2)
{1, 3, 5}
>>> s1
{1, 2, 3, 4, 5, 8, 10}
>>> s2
{2, 4, 6, 8, 10, 12}
>>> s1.difference_update(s2)
>>> s1
{1, 3, 5}
>>> s2
{2, 4, 6, 8, 10, 12}
>>>
>>>
>>>
>>> s1 = { 1, 2, 3, 4, 5, 8, 10}
>>> s2 = { 2, 4, 6, 8, 10, 12}
>>> s1
{1, 2, 3, 4, 5, 8, 10}
>>> s2
{2, 4, 6, 8, 10, 12}
>>> s1.intersection(s2)
{8, 2, 10, 4}
>>> s1
{1, 2, 3, 4, 5, 8, 10}
>>> s2
{2, 4, 6, 8, 10, 12}
>>> s1.intersection_update(s2)
>>> s1
{8, 2, 10, 4}
>>> s2
{2, 4, 6, 8, 10, 12}
>>>
>>>
>>>
>>> s1 = { 1, 2, 3, 4, 5, 8, 10}
>>> s2 = { 2, 4, 6, 8, 10, 12}
>>> s1
{1, 2, 3, 4, 5, 8, 10}
>>> s2
{2, 4, 6, 8, 10, 12}
>>> s1.symmetric_difference(s2)
{1, 3, 5, 6, 12}
>>> s1
{1, 2, 3, 4, 5, 8, 10}
>>> s2
{2, 4, 6, 8, 10, 12}
>>> s1.symmetric_difference_update(s2)
>>> s1
{1, 3, 5, 6, 12}
>>> s2
{2, 4, 6, 8, 10, 12}