1.3 ä¿�留最å�Ž N ä¸ªå…ƒç´ Â¶
问题¶
在è¿ä»£æ“�作或者其他æ“�ä½œçš„æ—¶å€™ï¼Œæ€Žæ ·å�ªä¿�留最å�Žæœ‰é™�å‡ ä¸ªå…ƒç´ çš„åŽ†å�²è®°å½•?
解决方案¶
ä¿�留有é™�历å�²è®°å½•æ£æ˜¯ collections.deque 大显身手的时候。比如,下é�¢çš„代ç �在多行上é�¢å�šç®€å�•的文本匹é…�,
并返回匹�所在行的最�N行:
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)
讨论¶
æˆ‘ä»¬åœ¨å†™æŸ¥è¯¢å…ƒç´ çš„ä»£ç �时,通常会使用包å�« yield 表达å¼�的生æˆ�器函数,也就是我们上é�¢ç¤ºä¾‹ä»£ç �ä¸çš„é‚£æ ·ã€‚
è¿™æ ·å�¯ä»¥å°†æ�œç´¢è¿‡ç¨‹ä»£ç �和使用æ�œç´¢ç»“果代ç �è§£è€¦ã€‚å¦‚æžœä½ è¿˜ä¸�清楚什么是生æˆ�器,请å�‚看 4.3 节。
使用 deque(maxlen=N) æž„é€ å‡½æ•°ä¼šæ–°å»ºä¸€ä¸ªå›ºå®šå¤§å°�çš„é˜Ÿåˆ—ã€‚å½“æ–°çš„å…ƒç´ åŠ å…¥å¹¶ä¸”è¿™ä¸ªé˜Ÿåˆ—å·²æ»¡çš„æ—¶å€™ï¼Œ
最è€�çš„å…ƒç´ ä¼šè‡ªåŠ¨è¢«ç§»é™¤æŽ‰ã€‚
代ç �示例:
>>> q = deque(maxlen=3)
>>> q.append(1)
>>> q.append(2)
>>> q.append(3)
>>> q
deque([1, 2, 3], maxlen=3)
>>> q.append(4)
>>> q
deque([2, 3, 4], maxlen=3)
>>> q.append(5)
>>> q
deque([3, 4, 5], maxlen=3)
å°½ç®¡ä½ ä¹Ÿå�¯ä»¥æ‰‹åŠ¨åœ¨ä¸€ä¸ªåˆ—è¡¨ä¸Šå®žçŽ°è¿™ä¸€çš„æ“�ä½œï¼ˆæ¯”å¦‚å¢žåŠ ã€�åˆ é™¤ç‰ç‰ï¼‰ã€‚ä½†æ˜¯è¿™é‡Œçš„é˜Ÿåˆ—æ–¹æ¡ˆä¼šæ›´åŠ ä¼˜é›…å¹¶ä¸”è¿�行得更快些。
更一般的, deque ç±»å�¯ä»¥è¢«ç”¨åœ¨ä»»ä½•ä½ å�ªéœ€è¦�一个简å�•队列数æ�®ç»“构的场å�ˆã€‚
å¦‚æžœä½ ä¸�设置最大队列大å°�ï¼Œé‚£ä¹ˆå°±ä¼šå¾—åˆ°ä¸€ä¸ªæ— é™�大å°�é˜Ÿåˆ—ï¼Œä½ å�¯ä»¥åœ¨é˜Ÿåˆ—çš„ä¸¤ç«¯æ‰§è¡Œæ·»åŠ å’Œå¼¹å‡ºå…ƒç´ çš„æ“�作。
代ç �示例:
>>> q = deque()
>>> q.append(1)
>>> q.append(2)
>>> q.append(3)
>>> q
deque([1, 2, 3])
>>> q.appendleft(4)
>>> q
deque([4, 1, 2, 3])
>>> q.pop()
3
>>> q
deque([4, 1, 2])
>>> q.popleft()
4
在队列两端æ�’å…¥æˆ–åˆ é™¤å…ƒç´ æ—¶é—´å¤�æ�‚度都是 O(1) ,区别于列表,在列表的开头æ�’å…¥æˆ–åˆ é™¤å…ƒç´ çš„æ—¶é—´å¤�æ�‚度为 O(N) 。