python动态映射_fluent python 3.7,3.8节 不可变映射类型和集合论

Python的MappingProxyType提供只读动态映射视图,防止用户修改原映射。集合则用于去重和高效运算,如合集、交集、差集。集合字面量和推导式简化创建与操作,frozenset适用于不可变集合。
摘要由CSDN通过智能技术生成

标准库里所有的映射类型都是可变的,但有时候你会有这样的需求,比如不能让用户错误地修改某个映射。

从 Python 3.3 开始,types 模块中引入了一个封装类名叫 MappingProxyType。如果给这个类一个映射,它会返回一个只读的映射视图。虽然是个只读视图,但是它是动态的。这意味着如果对原映射做出了改动,我们通过这个视图可以观察到,但是无法通过这个视图对原映射做出修改。

>>> from types import MappingProxyType

>>> d = {1:'A'}

>>> d_proxy = MappingProxyType(d)

>>> d_proxy

mappingproxy({1: 'A'})

>>> d_proxy[1]

'A'

>>> d_proxy[2] = 'x'

Traceback (most recent call last):

File "", line 1, in

TypeError: 'mappingproxy' object does not support item assignment

# 对d的修改会反馈到d_proxy上面

>>> d[2] = 'B'

>>> d_proxy

mappingproxy({1: 'A', 2: 'B'})

>>> d_proxy[2]

'B'

3.8 集合论

集合的本质是许多唯一对象的聚集。因此,集合可以用于去重:

>>> l = ['spam', 'spam', 'eggs', 'spam']

>>> set(l)

{'eggs', 'spam'}

>>> list(set(l))

['eggs', 'spam']

集合中的元素必须是可散列的,set 类型本身是不可散列的,但是 frozenset 可以。因此可以创建一个包含不同 frozenset 的 set。

除了保证唯一性,集合还实现了很多基础的中缀运算符。给定两个集合 a 和 b,a | b 返回的是它们的合集,a & b 得到的是交集,而 a - b 得到的是差集。合理地利用这些操作,不仅能够让代码的行数变少,还 能减少 Python 程序的运行时间。这样做同时也是为了让代码更易读,从 而更容易判断程序的正确性,因为利用这些运算符可以省去不必要的循环和逻辑操作。

needles 的元素在 haystack 里出现的次数

# 1.要求两个对象都是集合

found = len(needles & haystack)

# 2.两个对象为可迭代对象

found = 0

for n in needles:

if n in haystack:

found += 1

# 3.needles 的元素在 haystack 里出现的次数,这次的代 码可以用在任何可迭代对象上

found = len(set(needles) & set(haystack))

# 另一种写法:

found = len(set(needles).intersection(haystack))

除了速度极快的查找功能(这也得归功于它背后的散列表),内置的 set 和 frozenset 提供了丰富的功能和操作。

3.8.1 集合字面量

除空集之外,集合的字面量——{1}、{1, 2},等等——看起来跟它的 数学形式一模一样。如果是空集,那么必须写成 set() 的形式。

在 Python 3 里面,除了空集,集合的字符串表示形式总是以 {...} 的形 式出现。

>>> s = {1}

>>> type(s)

>>> s

{1}

>>> s.pop()

1

>>> s

set()

像 {1, 2, 3} 这种字面量句法相比于构造方法(set([1, 2, 3]))要更快且更易读。后者的速度要慢一些,因为 Python 必须先从 set 这个 名字来查询构造方法,然后新建一个列表,最后再把这个列表传入到构 造方法里。但是如果是像 {1, 2, 3} 这样的字面量,Python 会利用一 个专门的叫作 BUILD_SET 的字节码来创建集合。

由于 Python 里没有针对 frozenset 的特殊字面量句法,我们只能采用 构造方法。Python 3 里 frozenset 的标准字符串表示形式看起来就像构 造方法调用一样。

3.8.2 集合推导

例子:

>>> from unicodedata import name

>>> {chr(i) for i in range(32, 256) if 'SIGN' in name(chr(i),'')}

{'§', '=', '¢', '#', '¤', '

'°', '+', '÷', '±', '>', '¬', '®', '%'}

3.8.3 集合的操作

pass

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值