容器运算#
1. 合并#
1.1. 解包合并#
list01 = [1, 2, 3]
list02 = [4, 5, 6]
list03 = [*list01, *list02]
print("list03", list03)
# [1, 2, 3, 4, 5, 6]
profile = {"name": "xiaoming", "age": 27}
ext_info = {"gender": "male"}
full_profile01 = {**profile, **ext_info}
print(full_profile01)
# {'name': 'xiaoming', 'age': 27, 'gender': 'male'}
1.2. 内置方法#
list01 = [1, 2, 3]
list02 = [4, 5, 6]
list01.extend(list02)
print("list01", list01)
# [1, 2, 3, 4, 5, 6]
list03 = list01 + list02
print("list03", list03)
# [1, 2, 3, 4, 5, 6]
["a"]*10
# ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a']
profile = {"name": "xiaoming", "age": 27}
ext_info = {"gender": "male"}
profile.update(ext_info)
print(profile)
# {'name': 'xiaoming', 'age': 27, 'gender': 'male'}
new = profile | ext_info
print(new)
# {'name': 'xiaoming', 'age': 27, 'gender': 'male'}
1.3. 增量运算#
对列表 进行 +=
操作相当于 extend,而使用 =+
操作是新增了一个列表。
+=
其背后使用的魔法方法是__iadd__
,若没有实现这个方法则会退而求其次,使用__add__
。用列表举例a += b
,使用__add__
的话就像是使用了a.extend(b)
,若使用__add__
的话,则是a = a + b
,前者是直接在原列表上进行扩展,而后者是先从原列表中取出值,在一个新的列表中进行扩展,然后再将新的列表对象返回给变量,显然后者的消耗要大些。在遇到不可变序列时,增量运算会在背后生成新的序列。
# +=
a = [1, 2, 3, 4]
b = a
a += [5, 6, 7, 8]
print("a", a) # [1, 2, 3, 4, 5, 6, 7, 8]
print("b", b) # [1, 2, 3, 4, 5, 6, 7, 8]
# =+
a = [1, 2, 3, 4]
b = a
a = a + [5, 6, 7, 8]
print("a", a) # [1, 2, 3, 4, 5, 6, 7, 8]
print("b", b) # [1, 2, 3, 4]
# Find keys in common
a.keys() & b.keys() # { 'x', 'y' }
# Find (key, value) pairs in common
a.items() & b.items() # { ('y', 2) }
# Find keys in a that are not in b
a.keys() - b.keys() # { 'z' }
2. 配对#
x, y = [1, 2, 3], [4, 5, 6]
zipped = zip(x, y)
[*zipped] # [(1, 4), (2, 5), (3, 6)]
from itertools import zip_longest
x, y =[1, 2], [3]
[*zip_longest(x, y)] # [(1, 3), (2, None)]
3. 排序#
3.1. 关键字排序#
sort()
对字符串的大小写敏感,可指定 key
来避免这种影响。
sort()
返回值即自身,故无法被接收。-
可对数值类型逆序。对多个不同类型的
key
排序,需要分步进行。
places = ["home", "work", "New York", "Paris"]
places.sort()
print("Case sensitive: ", places)
places.sort(key=lambda x: x.lower())
print("Case insensitive:", places)
3.2. 迭代排序#
sorted(iterable, key, reverse=False)
对可迭代对象排序,无返回值。
# 绝对值排序
print(sorted([36, 5, -12, 9, -21], key=abs))
# 字符串排序
print(sorted(["bob", "about", "Zoo", "Credit"], key=str.lower))
# 按 value 排序
L = [("Bob", 75), ("Adam", 92), ("Bart", 66), ("Lisa", 88)]
d = dict(L)
print(sorted(d.items(), key=lambda x: x[1]))
对字典或 JSON 用 operator.itemgetter()
通常会运行得更快一些。这个同样适用于 min()
和 max()
这样的函数。
3.3. 合并排序#
heapq
模块里有一个 merge
方法,可以用于合并多个列表。
from heapq import merge
list01 = [1, 2, 3]
list02 = [4, 5, 6]
list03 = [7, 8, 9]
list04 = [*merge(list01, list02, list03)] # [1, 2, 3, 4, 5, 6, 7, 8, 9]
print("list04", list04)
4. 高阶函数#
Python 中有 3 个常用的迭代函数,其本质均为生成器。是由于引入了列表推导和生成器表达式,它 们变得没那么重要了。
4.1. map
#
map(func, iterable1, iterable2)
将传入的函数依次作用到序列的每个元素,并把结果迭代返回生成器对象。
# 函数需要一个参数
l = map(lambda x: x * x, [1, 2, 3])
print([*l])
#函数需要两个参数
def f1(x, y):
return x, y
l1 = [0, 1, 2, 3, 4, 5, 6]
l2 = ["Sun", "M", "T", "W", "T", "F", "S"]
l3 = map(f1, l1, l2)
print([*l3])
4.2. filter
#
filter(func/None, iterable)
,删除非 True
的内容,返回生成器对象。
# 判断奇数
l1 = filter(lambda x: x % 2, [1, 2, 3, 4])
print([*l1])
# 字符串判定
l2 = filter(None, "she")
print([*l2])
4.3. reduce
#
reduce(func, iterable/value)
把一个函数作用在一个序列上,把结果继续和序列的下一个元素递归累加。
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
from functools import reduce
l1 = reduce(lambda x, y: x + y, [1, 2, 3, 4], 5)
print(l1)
l2 = reduce(lambda x, y: x + y, ["aa", "bb", "cc"], "dd")
print(l2)
5. 其他#
5.1. 二分查找#
import bisect
def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
i = bisect.bisect(breakpoints, score)
return grades[i]
[grade(score) for score in [33, 99, 77, 70, 89, 90, 100]
] # ['F', 'A', 'C', 'C', 'B', 'A', 'A']
5.2. 插入#
import bisect
import random
SIZE = 7
random.seed(1729)
my_list = []
for i in range(SIZE):
new_item = random.randrange(SIZE * 2)
bisect.insort(my_list, new_item)
print('%2d ->' % new_item, my_list)
5.3. 不可变映射类型#
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 "<stdin>", line 1, in <module>
# TypeError: 'mappingproxy' object does not support item assignment
d[2] = 'B'
d_proxy
# mappingproxy({1: 'A', 2: 'B'})
d_proxy[2]
# 'B'