解压序列,赋值变量
变量数量和序列元素数量相同的时候可以实现多变量赋值,比如:
p = (2, 3)
a, b = p
# a=2, b=3
content = ["Linda", "Python", 100]
who, class, score = content
# who="Linda", class="Python", score=100
# 只想解压一部分,可以用任意变量名去占位
content = ["Linda", "Python", 100, "2017-01-03"]
who, _, score, _ = content
# who="Linda", score=100
# 不确定数量的解压,使用*
content = ["Linda", "Python", 100, 98, 100, "2017-01-03"]
who, class, *score, update_date = content
# who="Linda", class="Python", score=[100, 98, 100], update_date="2017-01-03"
content = ["Linda", "Python", 100, 98, 100, "2017-01-03"]
who, class, *_, update_date = content
# who="Linda", class="Python", update_date="2017-01-03"
deque
deque(maxlen=N)
构造函数新建固定大小的队列,当新的元素加入并且队列已满时,最老的元素会被去除。如果想 取序列倒数N个元素,可以将序列依次加入到大小为N的deque中。
如果不设置deque的大小,会得到一个无限大小的队列,可以在队列两端添加和弹出元素。
q = deque()
q.append("a")
q.appendleft("b")
q.pop()
q.popleft()
heapq
heapq
是python
里面的堆,具体来说是小顶堆,堆顶元素永远是最小的,所以可以使用heapq.heappop()
弹出剩余元素中最小的一个。heapq
模块有两个函数可以用来取最大或最小的N个元素,nlargest(n, sequence, key)
和nsmallest(n, sequence, key)
# 不指定关键字
import heapq
nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2] heapq.nlargest(3, nums) # [42, 37, 23]
heapq.nsmallest(3, nums) # [-4, 1, 2]
# 指定关键字
portfolio = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]
cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
# [
# {'name': 'YHOO', 'price': 16.35, 'shares': 45},
# {'name': 'FB', 'price': 21.09, 'shares': 200},
# ]
expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price'])
# [
# {'name': 'AAPL', 'price': 543.22, 'shares': 50},
# {'name': 'ACME', 'price': 115.65, 'shares': 75},
# ]
需要注意的是,在选取最大或者最小值的时候,heapq
并不是最优选择,通常使用max()
或者 min()
会更快一些。当N接近序列长度时,heapq
也不是很好的选择,这时,建议使用先排序再切片的方式,sorted(sequence)[:N]
或者 sorted(sequence)[-N:]
。
defaultdict & setdefault
一般dictionary
都是单值映射,在使用多值映射的时候可以考虑使用defaultdict
或者setdefault
,看例子:
from collections import defaultdict
d_list = defaultdict(list)
d_list["key1"].append(1)
d_list["key2"].append(2)
d_set = defaultdict(set)
d_set["key1"].add(1)
d_set["key2"].add(2)
这里defaultdict
有一个特性,不管之前是否存在要访问的键,在访问之前都会默认为它创建实体,也就是说,使用d["key"]
方式获取value
的时候,不存在“key”
这个关键字也不会报错了,也不同于get("key")
返回None
,它返回的是一个空的list
或者set
(这由你之前的定义决定)。不需要这种特性的话,可以选择在普通dict
中使用setdefault
。
d_normal = {}
d_normal.setdefault("a", []).append(1)
d_normal.setdefault("b", {}).add(1)
这里的setdefault
里面还可以同一个dict
的value
结构可以不一样,当然了用到这个的情况还没有遇到过。
OrderedDict
OrderedDict()可以保持元素的插入顺序。但是有一点需要注意,一个OrderedDict()消耗的空间是一个普通dict的两倍,这是因为OrderedDict()内部还要维护一个根据插入顺序排序双向链表,插入元素时,新插入的元素会被放在链表尾部,对于已经存在的键,重新赋值不会改变顺序。
【未完待更…】