python standard library -2 dictionary

python 标准库学习笔记 – dictionary

0.0 前言

家里孩子发烧了,延迟更新标准库学习笔记

折腾了三个晚上,一家三口都累倒了。

人生就好比一个蹒跚学步的孩童,很容易被外界环境影响。

1.0 标准库- 内置函数

参考文档: 内置类型-字典

python中主要内置类型包括numbers,sequences,mappings,classes,instanceexception

1.1 逻辑值检测

任何对象都可以进行逻辑值检测,以便在ifwhile作为条件或是作为上下文所指返回值是布尔类型的表达式来使用。所以就有下面的用法。

1
2
3
4
5
L = []
if(L):
pass
while(L):
pass

一个对象在默认情况下被认为是True,除非该对象定义了__boolean__() 方法且返回False 或者定义__len__()方法且返回零。下面三种情况的内置对象都会被认为是逻辑假值。

  • None 或 False

  • 任何数值类型的零

  • 空的序列和多项集 包括 空字符串、空列表、空集合、空字典、空元组以及空数列(reange(0))

1.2 布尔运算 – and,or,not

运算 结果 注释
x or y if x is false, then y, else x 短路运算,只有第一个为假的时候才会对第二个求值
x and y if x is false, then x, else y 短路运算,只有第二个为真的时候才会对第二个求值
not x if x is false, then True, else False 逻辑取反

1.3 比较运算

运算 含义
< 严格小于
<= 小于或等于
> 严格大于
>= 大于或等于
== 等于
!= 不等于
is 对象标识
is not 否定的对象标识

==tips==

  1. 不同类型的对象之间不能使用比较运算,除非定义了对应的方法,例如__lt__(),__eq__()这样的函数
  2. 具有不同标识的类的实例,比较结果为False,除非你自己定义了__eq__()方法
  3. 一个类实例不能与相同类或的其他实例或其他类型的对象进行排序,除非定义了对应的方法,包括 __lt__(), __le__(), __gt__() 以及 __ge__()

1.4 数字类型 – int、float、complex

python中存在三种不同的数字类型: 整数, 浮点数复数*。

运算 结果 注释 完整文档
x + y xy 的和
x - y xy 的差
x * y xy 的乘积
x / y xy 的商
x // y xy 的商数 取整
x % y remainder of x / y 不可用于负数
-x x 取反
+x x 不变
abs(x) x 的绝对值或大小 abs()
int(x) x 转换为整数 小数会被截断 int()
float(x) x 转换为浮点数 (4)(6) float()
complex(re, im) 一个带有实部 re 和虚部 im 的复数。im 默认为0。 (6) complex()
c.conjugate() 复数 c 的共轭
divmod(x, y) (x // y, x % y) (2) divmod()
pow(x, y) xy 次幂 (5) pow()
x ** y xy 次幂 (5)

所有的numbers.Real类型(包括intfloat)还包括以下运算:

运算 结果
math.trunc(x) x 截断为 Integral
round(x[, n\]) x 舍入到 n 位小数,半数值会舍入到偶数。 如果省略 n,则默认为 0。
math.floor(x) <= x 的最大 Integral
math.ceil(x) >= x 的最小 Integral

1.5 整数类型的附加方法

int.bit_length()

返回以二进制表示一个整数锁需要的位数,不包括符号位和前面的零

1.6 浮点数类型的附加方法

float.as_integer_ratio()

返回一对整数,其比率正好等于原浮点数并且分母为正数。 无穷大会引发 OverflowError 而 NaN 则会引发 ValueError

float.is_integer()

如果 float 实例可用有限位整数表示则返回 True,否则返回 False:

float.hex()

以十六进制字符串的形式返回一个浮点数表示。 对于有限浮点数,这种表示法将总是包含前导的 0x 和尾随的 p 加指数。

classmethod float.fromhex(s)

返回以十六进制字符串 s 表示的浮点数的类方法。 字符串 s 可以带有前导和尾随的空格。

==tips==: float.hex() 是实例方法, float.fromhex(s)是类方法

1
2
3
4
>>> float.fromhex('0x3.a7p10')
3740.0
>>> float.hex(3740.0)
'0x1.d380000000000p+11'

1.7 数字类型的哈希运算

一个例子说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import sys, math

def hash_fraction(m, n):
"""Compute the hash of a rational number m / n.

Assumes m and n are integers, with n positive.
Equivalent to hash(fractions.Fraction(m, n)).

"""
P = sys.hash_info.modulus
# Remove common factors of P. (Unnecessary if m and n already coprime.)
while m % P == n % P == 0:
m, n = m // P, n // P

if n % P == 0:
hash_value = sys.hash_info.inf
else:
# Fermat's Little Theorem: pow(n, P-1, P) is 1, so
# pow(n, P-2, P) gives the inverse of n modulo P.
hash_value = (abs(m) % P) * pow(n, P - 2, P) % P
if m < 0:
hash_value = -hash_value
if hash_value == -1:
hash_value = -2
return hash_value

def hash_float(x):
"""Compute the hash of a float x."""

if math.isnan(x):
return sys.hash_info.nan
elif math.isinf(x):
return sys.hash_info.inf if x > 0 else -sys.hash_info.inf
else:
return hash_fraction(*x.as_integer_ratio())

def hash_complex(z):
"""Compute the hash of a complex number z."""

hash_value = hash_float(z.real) + sys.hash_info.imag * hash_float(z.imag)
# do a signed reduction modulo 2**sys.hash_info.width
M = 2**(sys.hash_info.width - 1)
hash_value = (hash_value & (M - 1)) - (hash_value & M)
if hash_value == -1:
hash_value = -2
return hash_value

1.8 映射类型 – dict

python中目前只有一种映射类型, 字典,映射属于可变对象。映射类型会将hashtable值映射到任意对象.

字典的键 几乎可以是任意值, 可hash的任意值,也就是包含列表、字典和其他可变类型的值,不可以用来充当字典中的键。

1.创建字典

字典可以通过将以逗号分隔的 键: 值 对列表包含于花括号之内来创建,例如: {'jack': 4098, 'sjoerd': 4127}{4098: 'jack', 4127: 'sjoerd'},也可以通过 dict 构造器来创建。

2.构造函数

class dict(**kwarg)

class dict(mapping, **kwarg)

class dict(iterable, **kwarg)

3. 其他函数

函数名 描述
list(d) 返回字典 d 中使用的所有键的列表。
len(d) 返回字典 d 中的项数。
d[key] 返回 d 中以 key 为键的项。 如果映射中不存在 key 则会引发 KeyError [1]
d[key] = value 给d[key]的值设为value
del d[key] d[key]d 中移除。 如果映射中不存在 key 则会引发 KeyError
key in d 如果 d 中存在键 key 则返回 True,否则返回 False
key not in d 等价于 not key in d
iter(d) 返回以字典的键为元素的迭代器
clear() 移除字典中的所有元素。
copy() 返回原字典的浅拷贝。
classmethod fromkeys(iterable[, value]) 使用来自 iterable 的键创建一个新字典,并将键值设为 value
get(key[, default]) 如果 key 存在于字典中则返回 key 的值,否则返回 default。 如果 default 未给出则默认为 None,因而此方法绝不会引发 KeyError
items() 返回由字典项 ((键, 值) 对) 组成的一个新视图。
keys() 返回由字典键组成的一个新视图
pop(key[, default]) 如果 key 存在于字典中则将其移除并返回其值,否则返回 default。 如果 default 未给出且 key 不存在于字典中,则会引发 KeyError
popitem() 从字典中移除并返回一个 (键, 值) 对。 键值对会按 LIFO 的顺序被返回。
reversed(d) 返回一个逆序获取字典键的迭代器
setdefault(key[, default]) 如果字典存在键 key ,返回它的值。如果不存在,插入值为 default 的键 key ,并返回 defaultdefault 默认为 None
update([other]) 使用来自 other 的键/值对更新字典,覆盖原有的键。
values() 返回由字典值组成的一个新视图 [2]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#[1] 如果字典的子类定义了方法 __missing__() 并且 key 不存在,则 d[key] 操作将调用该方法并附带键 key 作为参数。 d[key] 随后将返回或引发 __missing__(key) 调用所返回或引发的任何对象或异常。 没有其他操作或方法会发起调用 __missing__()。 如果未定义 __missing__(),则会引发 KeyError。 __missing__() 必须是一个方法;它不能是一个实例变量:
>>> class Counter(dict):
... def __missing__(self, key):
... return 0
>>> c = Counter()
>>> c['red']
0
>>> c['red'] += 1
>>> c['red']
1
#[2]两个 dict.values() 视图之间的相等性比较将总是返回 False。 这在 dict.values() 与其自身比较时也同样适用:
>>> d = {'a': 1}
>>> d.values() == d.values()
False

字典比较:

两个字典的比较当且仅当它们具有相同的 (键, 值) 对时才会相等(不考虑顺序)。 排序比较 (‘<’, ‘<=’, ‘>=’, ‘>’) 会引发 TypeError

字典会保留插入时的顺序。 请注意对键的更新不会影响顺序。 删除并再次添加的键将被插入到末尾。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> d = {"one": 1, "two": 2, "three": 3, "four": 4}
>>> d
{'one': 1, 'two': 2, 'three': 3, 'four': 4}
>>> list(d)
['one', 'two', 'three', 'four']
>>> list(d.values())
[1, 2, 3, 4]
>>> d["one"] = 42
>>> d
{'one': 42, 'two': 2, 'three': 3, 'four': 4}
>>> del d["two"]
>>> d["two"] = None
>>> d
{'one': 42, 'three': 3, 'four': 4, 'two': None}

4.字典视图对象

dict.keys(), dict.values()dict.items() 所返回的对象是 视图对象。 该对象提供字典条目的一个动态视图,这意味着当字典改变时,视图也会相应改变。

字典视图函数 描述
len(dictview) 返回字典中的条目数
iter(dictview) 返回字典中的键、值或项(以 (键, 值) 为元素的元组表示)的迭代器 [1]
x in dictview 如果 x 是对应字典中存在的键、值或项(在最后一种情况下 x 应为一个 (键, 值) 元组) 则返回 True
reversed(dictview) 返回一个逆序获取字典键、值或项的迭代器。 视图将按与插入时相反的顺序进行迭代。 [2]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#键视图类似于集合,因为其条目不重复且可哈希。 如果所有值都是可哈希的,即 (键, 值) 对也是不重复且可哈希的,那么条目视图也会类似于集合。 (值视图则不被视为类似于集合,因其条目通常都是有重复的。) 对于类似于集合的视图,为抽象基类 collections.abc.Set 所定义的全部操作都是有效的 (例如 ==, < 或 ^)。
>>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
>>> keys = dishes.keys()
>>> values = dishes.values()

>>> # iteration
>>> n = 0
>>> for val in values:
... n += val
>>> print(n)
504

>>> # keys and values are iterated over in the same order (insertion order)
>>> list(keys)
['eggs', 'sausage', 'bacon', 'spam']
>>> list(values)
[2, 1, 1, 500]

>>> # view objects are dynamic and reflect dict changes
>>> del dishes['eggs']
>>> del dishes['sausage']
>>> list(keys)
['bacon', 'spam']

>>> # set operations
>>> keys & {'eggs', 'bacon', 'salad'}
{'bacon'}
>>> keys ^ {'sausage', 'juice'}
{'juice', 'sausage', 'bacon', 'spam'}

2.0 小结

  1. 字典是可变类型,键只能是由非hash的数据类型充当

  2. 字典子类的__missing__方法。

  3. 字典视图的元素为不重复且可哈希。

    一张图总结如下

后记

记得五年前听过的一句话,赠给自己,也赠给凑巧看到这篇博文的有缘人。

种一棵树最好的时间是在十年前,其次是现在。

坚持原创技术分享,您的支持将鼓励我继续创作!