解壓序列賦值多個(gè)變量
data=['AC',51,29.1,(2012,12,21)]
name,shares,price,date=data
name, shares, price, (year, mon, day) = data
如果變量個(gè)數(shù)和序列元素的個(gè)數(shù)不匹配,會(huì)產(chǎn)生一個(gè)異常。
可以使用任意變量名去占位,到時(shí)候丟掉這些變量就行了
_, shares, price, _ = data
解壓可迭代對(duì)象賦值給多個(gè)變量
record = ('Dave', 'dave@example.com', '773-555-1212', '847-555-1212')
name,email,*phone_numbers=record
>>> phone_numbers
['773-555-1212', '847-555-1212']
迭代元素為可變長(zhǎng)元祖的序列
records = [
('foo', 1, 2),
('bar', 'hello'),
('foo', 3, 4),
]
def do_foo(x, y):
print('foo', x, y)
def do_bar(s):
print('bar', s)
for tag, *args in records:
if tag == 'foo':
do_foo(*args)
elif tag == 'bar':
do_bar(*args)
星號(hào)解壓語(yǔ)法在字符串操作
>>> line = 'nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false'
>>> uname, *fields, homedir, sh = line.split(':')
解壓一些元素后丟棄,使用一個(gè)普通的廢棄名稱
>>> record = ('ACME', 50, 123.45, (12, 18, 2012))
>>> name, *_, (*_, year) = record
保留最后N個(gè)元素
collections.deque
使用 deque(maxlen=N) 構(gòu)造函數(shù)會(huì)新建一個(gè)固定大小的隊(duì)列。當(dāng)新的元素加入并且這個(gè)隊(duì)列已滿的時(shí)候, 最老的元素會(huì)自動(dòng)被移除掉。
from collections import deque
def search(lines, pattern, history=5):
previous_lines = deque(maxlen=history)
for line in lines:
if pattern in line:
yield line, previous_lines
previous_lines.append(line)
# Example use on a file
if __name__ == '__main__':
with open(r'../../cookbook/somefile.txt') as f:
for line, prevlines in search(f, 'python', 5):
for pline in prevlines:
print(pline, end='')
print(line, end='')
print('-' * 20)
q=deque()
q.append(1)
q.appendleft(4)
q.pop()
q.popleft()
查找最大或最小的N個(gè)元素
import heapq
import heapq
nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
print(heapq.nlargest(3, nums)) # Prints [42, 37, 23]
print(heapq.nsmallest(3, nums)) # Prints [-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'])
expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price'])
在一個(gè)集合中查找最大或者最小的N個(gè)元素
>>> nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
>>> import heapq
>>> heap = list(nums)
>>> heapq.heapify(heap)
>>> heap
[-4, 2, 1, 23, 7, 2, 18, 23, 42, 37, 8]
heapq.heappop(head) 將彈出剩余最小的元素
>>> heapq.heappop(heap)
-4
>>> heapq.heappop(heap)
1
>>> heapq.heappop(heap)
2
- 當(dāng)要查找元素個(gè)數(shù)相對(duì)較小的時(shí)候,函數(shù)nlargest()和nsmallest()很合適
- 查詢唯一的最小或最大的元素max()和min()
- 如果N的大小和集合大小接近的時(shí)候。通常先排序在切片 sorted(items)[:N]
實(shí)現(xiàn)一個(gè)隊(duì)列的優(yōu)先級(jí)
import heapq
class PriorityQueue:
def __init__(self):
self._queue = []
self._index = 0
def push(self, item, priority):
heapq.heappush(self._queue, (-priority, self._index, item))
self._index += 1
def pop(self):
return heapq.heappop(self._queue)[-1]
>>> class Item:
... def __init__(self, name):
... self.name = name
... def __repr__(self):
... return 'Item({!r})'.format(self.name)
...
>>> q = PriorityQueue()
>>> q.push(Item('foo'), 1)
>>> q.push(Item('bar'), 5)
>>> q.push(Item('spam'), 4)
>>> q.push(Item('grok'), 1)
>>> q.pop()
Item('bar')
>>> q.pop()
Item('spam')
>>> q.pop()
Item('foo')
>>> q.pop()
Item('grok')
>>>
pop() 操作返回優(yōu)先級(jí)最高的元素,如果二個(gè)有著相同優(yōu)先級(jí)的元素,pop 操作按照他們的順序被插入到隊(duì)列的順序返回。
_index 變量的作用是保證同等優(yōu)先級(jí)元素的正確排序
原理:
1.假定Item實(shí)例不支持排序:
>>> a = Item('foo')
>>> b = Item('bar')
>>> a < b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: Item() < Item()
>>>
2.使用元祖(priority, item),只要二個(gè)元素的優(yōu)先級(jí)不同就能比較,優(yōu)先級(jí)一樣的話,比較就會(huì)出錯(cuò)。
>>> a = (1, Item('foo'))
>>> b = (5, Item('bar'))
>>> a < b
True
>>> c = (1, Item('grok'))
>>> a < c
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: Item() < Item()
>>>
3.引入index 變量組成三元組 (priority, index, item),就能很好的避免錯(cuò)誤,因?yàn)椴豢赡苡卸€(gè)元素有相同的index值。
>>> a = (1, 0, Item('foo'))
>>> b = (5, 1, Item('bar'))
>>> c = (1, 2, Item('grok'))
>>> a < b
True
>>> a < c
True
>>>
字典中的鍵映射多個(gè)值(multidict)
collections 模塊中的 defaultdict 來構(gòu)造這樣的字典。 defaultdict 的一個(gè)特征是它會(huì)自動(dòng)初始化每個(gè) key 剛開始對(duì)應(yīng)的值,所以你只需要關(guān)注添加元素操作了。
from collections import defaultdict
d = defaultdict(list)
d['a'].append(1)
d['a'].append(2)
d['b'].append(4)
defaultdict(<class 'list'>, {'a': [1, 2], 'b': [4]})
d = defaultdict(set)
d['a'].add(1)
d['a'].add(2)
d['b'].add(4)
defaultdict(<class 'set'>, {'a': {1, 2}, 'b': {4}})
d = {} # 一個(gè)普通的字典
d.setdefault('a', []).append(1)
d.setdefault('a', []).append(2)
d.setdefault('b', []).append(4)
{'a': [1, 2], 'b': [4]}
字典排序
1.保持元素的插入順序
from collections import OrderedDict
from collections import OrderedDict
d = OrderedDict()
d['foo'] = 1
d['bar'] = 2
d['spam'] = 3
d['grok'] = 4
# Outputs "foo 1", "bar 2", "spam 3", "grok 4"
for key in d:
print(key, d[key])
OrderedDict 內(nèi)部維護(hù)著一個(gè)根據(jù)鍵插入順序排序的雙向鏈表。
每次當(dāng)一個(gè)新的元素插入進(jìn)來的時(shí)候, 它會(huì)被放到鏈表的尾部。對(duì)于一個(gè)已經(jīng)存在的鍵的重復(fù)賦值不會(huì)改變鍵的順序。
字典的運(yùn)算
zip()函數(shù)先將鍵和值反轉(zhuǎn)過來
prices = {
'ACME': 45.23,
'AAPL': 612.78,
'IBM': 205.55,
'HPQ': 37.20,
'FB': 10.75
}
a=zip(prices.values(), prices.keys())
for i in a:
print(i)
(10.75, 'FB')
(45.23, 'ACME')
(205.55, 'IBM')
(612.78, 'AAPL')
(37.2, 'HPQ')
min_price = min(zip(prices.values(), prices.keys()))
# min_price is (10.75, 'FB')
max_price = max(zip(prices.values(), prices.keys()))
# max_price is (612.78, 'AAPL')
可以使用 zip() 和 sorted() 函數(shù)來排列字典數(shù)據(jù):
prices_sorted = sorted(zip(prices.values(), prices.keys()))
# prices_sorted is [(10.75, 'FB'), (37.2, 'HPQ'),
# (45.23, 'ACME'), (205.55, 'IBM'),
# (612.78, 'AAPL')]
執(zhí)行這些計(jì)算的時(shí)候,需要注意的是 zip() 函數(shù)創(chuàng)建的是一個(gè)只能訪問一次的迭代器
prices_and_names = zip(prices.values(), prices.keys())
print(min(prices_and_names)) # OK
print(max(prices_and_names)) # ValueError: max() arg is an empty sequence
當(dāng)多個(gè)實(shí)體擁有相同的值的時(shí)候,鍵會(huì)決定返回結(jié)果。 比如,在執(zhí)行 min() 和 max() 操作的時(shí)候,如果恰巧最小或最大值有重復(fù)的,那么擁有最小或最大鍵的實(shí)體會(huì)返回:
>>> prices = { 'AAA' : 45.23, 'ZZZ': 45.23 }
>>> min(zip(prices.values(), prices.keys()))
(45.23, 'AAA')
>>> max(zip(prices.values(), prices.keys()))
(45.23, 'ZZZ')
>>>
查找倆字典的相同點(diǎn)(相同的鍵、相同的值)
a = {
'x' : 1,
'y' : 2,
'z' : 3
}
b = {
'w' : 10,
'x' : 11,
'y' : 2
}
# Find keys in common
a.keys() & b.keys() # { 'x', 'y' }
# Find keys in a that are not in b
a.keys() - b.keys() # { 'z' }
# Find (key,value) pairs in common
a.items() & b.items() # { ('y', 2) }
c = {key:a[key] for key in a.keys() - {'z', 'w'}}
# c is {'x': 1, 'y': 2}
刪除序列相同元素并保持順序