Python字典与集合

1.字典

字典通过键值对(key:value)的方式,把key映射到value,key必须是可hash的(hashable),由于python中所有内置的不可变类型(immutable)都是可以hash的,所以都可以用作字典的key,比如字符串(str)、数字(int,float)和只包含不可变类型元素的元组(tuple),如果元组直接或间接的包含了可变类型的元素,也不能作为字典的key,value则可以是任意类型。
字典中元素是无序的,并不会按照插入的顺序排序,可能会是任意的顺序,如果想要有序的字典,可以使用collections.OreredDict。但是从Python3.7开始,字典默认是按照插入顺序排序的了。

1.1字典的创建
创建一个字典可以通过以下3种方式:

  • 大括号{}方式:
>>> d = {'name':'lili','age':18}
>>> d
{'name': 'lili', 'age': 18}
  • dict关键字方式:
    dict的定义如下:
class dict(**kwarg)
class dict(mapping, **kwarg)
class dict(iterable, **kwarg)

根据定义dict接受如下形式的参数进行初始化:

>>> dict(one=1, two=2) # 关键字参数形式(**kwargs)
{'one': 1, 'two': 2}
>>> dict({'one':1, 'two':2}) # 字典形式(mapping)
{'one': 1, 'two': 2}
>>> dict([('one',1), ['two',2]]) # 可迭代类型中内嵌2个元素的可迭代类型(iterable)
{'one': 1, 'two': 2}
>>> dict({'one':1}, two=2) # 字典+关键字参数形式(mapping + **kwargs)
{'one': 1, 'two': 2}
>>> dict([('one',1)], two=2) # 可迭代类型+关键字参数形式(iterable + **kwargs)
{'one': 1, 'two': 2}
  • 字典推导式(dict comprehension):
>>> {x: x**2 for x in (2,4,6)}
{2: 4, 4: 16, 6: 36}

1.2字典操作

  • len(d)
    返回字典d的长度,即包含多少个键值对
>>> d = {'one':1, 'two':2}
>>> len(d)
2
  • d[key]
    返回key对应的value,如果key不存在,则抛出KeyError异常
>>> d = {'one':1, 'two':2}
>>> d['one']
1
>>> d['three']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'three'
  • d[key] = value
    设置key对应的value,如果key不存在则自动添加
>>> d = {'one':1, 'two':2}
>>> d['two'] = 2.0
>>> d['three'] = 3
>>> d
{'one': 1, 'two': 2.0, 'three': 3}
  • del d[key]
    删除key对应的项,如果key不存在则抛出KeyError异常
>>> d = {'one':1, 'two':2}
>>> del d['two']
>>> d
{'one': 1}
  • pop(key[,default])
    删除key对应的项,并返回对应的value,如果key不存在并且传入了default参数,那么返回default,否则抛出KeyError异常
>>> d = {'one':1, 'two':2}
>>> d.pop('two')
2
>>> d.pop('three',0)
0
>>> d
{'one': 1}
  • popitem()
    任意删除并返回一个项,由于字典是无序的,所以删除的项是不确定的
>>> d = {'one':1, 'two':2}
>>> d.popitem()
('two', 2)
>>> d
{'one': 1}

从python3.7开始字典是有序的(按照插入顺序排序),所以popitem()会按照LIFO规则删除,即相当于删除最后一个项

  • key in d
    如果key存在于字典d中,则返回True,否则返回False
>>> d = {'one':1, 'two':2}
>>> 'one' in d
True
>>> 'three' in d
False
  • key not in d
    如果key不存在于字典d中,则返回True,否则返回False
>>> d = {'one':1, 'two':2}
>>> 'one' not in d
False
>>> 'three' not in d
True
  • iter(d)
    返回一个包含字典d的所有key的迭代器(iterator)
>>> d = {'one':1, 'two':2}
>>> for k in iter(d):
...     print(k)
...
one
two
  • clear()
    清空字典
>>> d = {'one':1, 'two':2}
>>> d.clear()
>>> d
{}
  • copy()
    返回字典的浅拷贝
>>> d1 = {'one':1, 'two':2}
>>> d2 = d1.copy()
>>> d2
{'one': 1, 'two': 2}
  • classmethod fromkeys(seq[, value])
    返回一个新的字典,字典的keys来自参数seq,并且所有key的value为参数value,value参数默认值为None。
>>> dict.fromkeys(['three','four'])
{'three': None, 'four': None}
>>> dict.fromkeys(['three','four'],0)
{'three': 0, 'four': 0}
  • get(key[, default])
    返回key对应的value,如果key不存在则返回default,default默认为None
>>> d = {'one':1, 'two':2}
>>> d.get('one')
1
>>> d.get('three',0)
0
  • items()
    返回一个包含所有项的字典视图(view),每一项是2个元素的tuple。分别为key和value
>>> d = {'one':1, 'two':2}
>>> for k,v in d.items():
...     print('%s = %s' % (k,v))
...
one = 1
two = 2
  • keys()
    返回一个包含所有key的字典视图
>>> d = {'one':1, 'two':2}
>>> for k in d.values():
...     print(k)
...
one
two
  • values()
    返回一个包含所有value的字典视图
>>> d = {'one':1, 'two':2}
>>> for v in d.values():
...     print(v)
...
1
2
  • setdefault(key[, default])
    如果key存在于字典中,则返回其对应的value,否则插入key,并且将其value设置为default,default默认为None
>>> d = {'one':1, 'two':2}
>>> d.setdefault('two')
2
>>> d.setdefault('three',3)
3
>>> d
{'one': 1, 'two': 2, 'three': 3}
  • update([other])
    更新字典中的项,可接受参数类型与dict关键字一样
>>> d = {'one':1, 'two':2}
>>> d.update({'two':2.0,'three':3}) # mapping形式
>>> d
{'one': 1, 'two': 2.0, 'three': 3}
>>> d.update([('three',3.0),('four',4)]) # iterable形式
>>> d
{'one': 1, 'two': 2.0, 'three': 3.0, 'four': 4}
>>> d.update(five=5,six=6) # **kwargs形式
>>> d
{'one': 1, 'two': 2.0, 'three': 3.0, 'four': 4, 'five': 5, 'six': 6}
>>> d.update({'six':6.0},seven=7) # mapping + **kwargs形式
>>> d
{'one': 1, 'two': 2.0, 'three': 3.0, 'four': 4, 'five': 5, 'six': 6.0, 'seven': 7}
>>> d.update([('one',1.0),('four',4.0)],five=5.0,seven=7.0) # iterable + **kwargs形式
>>> d
{'one': 1.0, 'two': 2.0, 'three': 3.0, 'four': 4.0, 'five': 5.0, 'six': 6.0, 'seven': 7.0}

1.3字典视图
上面提到的d.keys()、d.values()和d.items()等方法返回的都是一个视图类型(view object),通过这些视图可以访问字典d的keys、values或items,并且视图会随着字典的变化而自动更新。

>>> d = {'one':1, 'two':2}
>>> keys = d.keys()
>>> values = d.values()
>>> items = d.items()
>>> keys
dict_keys(['one', 'two'])
>>> values
dict_values([1, 2])
>>> items
dict_items([('one', 1), ('two', 2)])

# 视图随着字典变化而动态更新
>>> d.update(three=3)
>>> keys
dict_keys(['one', 'two', 'three'])
>>> values
dict_values([1, 2, 3])
>>> items
dict_items([('one', 1), ('two', 2), ('three', 3)])
>>>
>>> for k in keys:
...     print(k)
...
one
two
three

1.4字典比较
字典只支持==比较操作符,仅当所有项都相等时才相等,对于<、>、<=、>=比较操作符都不支持,如果使用会抛TypeError错误。

2.集合

集合(set)是一些无序、无重复并且可hash元素的组合。通常用于是否包含某个成员的检测、去除重复元素等操作。同时也支持数学上的集合运算,比如交集、并集、差集和对称差集。
Python内置2中类型集合,set和frozenset,set是可变类型,frozenset是不可变类型。

2.1集合创建
集合创建可以通过以下2种方式:

  • 大括号{}方式
>>> s = {'a','b','c','a'}
>>> s
{'a', 'b', 'c'} # 元素相等只能保留一个
  • set或frozenset关键字方式
    set和frozenset的定义如下:
class set([iterable])
class frozenset([iterable])

根据以上定义可以通过下面的方式创建集合:

>>> s = set(['a','b','c'])
>>> fs = frozenset(['a','b','c'])
>>> s
{'a', 'b', 'c'}
>>> fs
frozenset({'a', 'b', 'c'})
>>> s.add('d') # set是可变类型
>>> s
{'a', 'b', 'd', 'c'}
>>> fs.add('d') # frozenset是不可变类型
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'frozenset' object has no attribute 'add
  • 集合推导式
>>> {x for x in range(1,11)}
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

集合中的元素必须是可以hash的:

# str、number和tuple类型都是可以hash的
>>> {'one',2,(3,4)}
{'one', 2, (3, 4)}

# list是不可hash(unhashable)类型
>>> {1,[2]}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

# 间接包含unhashable也不行
>>> {1,(2,[3])}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

如果要创建空集合,必须使用set或frozenset关键字,不能使用大括号,因为{}创建的是一个空字典。

>>> s = set()
>>> s
set()
>>> fs = frozenset()
>>> fs
frozenset()
>>> d = {}
>>> d
{}
>>> type(d)
<class 'dict'>

2.2集合操作
以下是set和frozenset都支持的操作:

  • len(s)
    返回结合中元素的个数
>>> s = {1,2}
>>> len(s)
2
  • x in s
    判断x是否被包含于集合s中
>>> s = {1,2}
>>> 1 in s
True
>>> 3 in s
False
  • x not in s
    判断x是否不被包含于集合s中
>>> s = {1,2}
>>> 1 not in s
False
>>> 3 not in s
True
  • isdisjoint(other)
    判断当前集合是否与其它集合other没有交集
>>> s = {1,2}
>>> s.isdisjoint({3,4})
True
>>> s.isdisjoint({2,3})
False
  • issubset(other)
    set <= other
    判断当前集合是否为其它集合other的子集
    子集:指一个集合中的所有元素都属于另一个集合
>>> s = {1,2}
>>> other = {1,2,3}
>>> s.issubset(other)
True
>>> s <= other
True
>>> other = {1,4,3}
>>> s.issubset(other)
False
>>> s <= other
False
  • set < other
    判断当前集合是否为其它集合other的真子集
    真子集:指一个集合中的所有元素都属于另一个集合,但这两个集合并不完全相同
>>> {1,2} < {1,2,3}
True
>>> {1,2} < {1,2}
False
  • issuperset(other)
    set >= other
    判断当前集合是否为其它集合other的超集。
    如果一个集合S2中的每一个元素都在集合S1中,且集合S1中可能包含S2中没有的元素,则集合S1就是S2的一个超集,反过来,S2是S1的子集。
>>> s = {1,2,3}
>>> other = {1,2}
>>> s.issuperset(other)
True
>>> s >= other
True
  • set > other
    判断当前集合是否是其它集合other的真超集
    S1是S2的超集,若S1中一定有S2中没有的元素,则S1是S2的真超集,反过来S2是S1的真子集。
>>> {1,2,3} > {1,2}
True
>>> {1,2} > {1,2}
False
  • union(*others)
    set | other | …
    当前集合与其它一个或多个集合求并集
>>> s = {1,2}
>>> other = {2,3}
>>> s.union(other)
{1, 2, 3}
>>> s | other
{1, 2, 3}
  • intersection(*others)
    set & other & …
    当前集合与其它一个或多个集合求交集
>>> s = {1,2}
>>> other = {2,3}
>>> s.intersection(other)
{2}
>>> s & other
{2}
  • difference(*others)
    set - other - …
    当前集合与其它一个或多个集合求差集
>>> s = {1,2}
>>> other = {2,3}
>>> s.difference(other)
{1}
>>> s - other
{1}
  • symmetric_difference(other)
    set ^ other
    当前集合与其它集合other求对称差集
>>> s = {1,2}
>>> other = {2,3}
>>> s ^ other
{1, 3}
>>> s.symmetric_difference(other)
{1, 3}
  • copy()
    返回当前集合的一个浅拷贝
>>> s = {1,2}
>>> s.copy()
{1, 2}

需要注意的是以上的比较方法union()、intersection()、difference()、symmetric_difference()、issubset()和issuperser(),接受的参数除了集合类型外,还可以是可迭代类型(iterable)。相比之下,对应的比较运算符只能接受集合类型参数。

>>> {1,2}.union([3,4]) # union方法可以接受iterable类型
{1, 2, 3, 4}
>>> {1,2} | [3,4] # | 运算符不能接受iterable类型
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'set' and 'list'

以下是只有set支持的操作:

  • update(*others)
    set |= other |= …
    将当前集合与其它一个或多个集合求并集,然后更新到当前集合
>>> s = {1,2}
>>> other = {2,3}
>>> s.update(other)
>>> s
{1, 2, 3}
>>> s |= {3,4}
>>> s
{1, 2, 3, 4}
  • intersection_update(*other)
    set &= other &= …
    将当前集合与其它一个或多个集合求交集,然后更新到当前集合
>>> s = {1,2}
>>> other = {2,3}
>>> s.intersection_update(other)
>>> s
{2}
>>> s &= {3,4}
>>> s
set()
  • add(elem)
    添加一个元素elem到当前集合
>>> s = {1,2}
>>> s.add(3)
>>> s
{1, 2, 3}
  • remove(elem)
    从当前集合删除元素elem,如果elem不存在则抛KeyError异常
>>> s = {1,2}
>>> s.remove(2)
>>> s
{1}
>>> s.remove(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 2
  • discard(elem)
    从当前集合删除元素elem,如果elem不存在也不抛异常
>>> s = {1,2}
>>> s.discard(2)
>>> s
{1}
>>> s.discard(2)
>>> s
{1}
  • pop()
    从当前集合任意删除一个元素并返回,由于集合是无序的,所以删除哪个元素不确定,如果当前集合为空,则抛KeyError异常
>>> s = {1,2}
>>> s.pop()
1
>>> s.pop()
2
>>> s.pop()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'pop from an empty set'
  • clear()
    清空当前集合
>>> s = {1,2}
>>> s.clear()
>>> s
set()

同样的以上的update()、intersection_update()和symmetric_difference_update()也可以接受可迭代类型参数,但对应的运算符只能接受集合类型参数。

3.immutable和hashable

Python中不可变类型immutable都是hashable类型的,但是hashable类型并不一定都是immutable的,因为默认所有自定义类的实例都是hashable类型的,其hash值通常就是id()函数的计算结果,由于用户自定义类型不一定是不可变类型,所以hashable类型不一定都是immutable类型的。

  • 22
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值