From afff86f0a6f8224a2bd0ec6c299115cb09dd04d0 Mon Sep 17 00:00:00 2001 From: XiongNeng Date: Mon, 1 Sep 2014 01:13:58 +0800 Subject: [PATCH] =?UTF-8?q?1.3=E8=8A=82=E7=BF=BB=E8=AF=91=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cookbook/c01/p03_nitem.py | 27 ++++++++++ cookbook/somefile.txt | 19 +++++++ source/c01/p03_keep_last_n_items.rst | 80 ++++++++++++++++++++++++++-- 3 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 cookbook/c01/p03_nitem.py create mode 100644 cookbook/somefile.txt diff --git a/cookbook/c01/p03_nitem.py b/cookbook/c01/p03_nitem.py new file mode 100644 index 0000000..0a857f3 --- /dev/null +++ b/cookbook/c01/p03_nitem.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +""" +Topic: collections.deque演示 +Desc : deque有一个maxlen参数,当append的时候,如果超过,那么最前面的就被挤出队列。 +""" +from collections import deque + + +def search(lines, pattern, history=5): + previous_lines = deque(maxlen=history) + for li in lines: + if pattern in li: + yield li, previous_lines + previous_lines.append(li) + +# 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) + + + diff --git a/cookbook/somefile.txt b/cookbook/somefile.txt new file mode 100644 index 0000000..243b7c4 --- /dev/null +++ b/cookbook/somefile.txt @@ -0,0 +1,19 @@ +Python is powerful... and fast; +plays well with others; +runs everywhere; +is friendly & easy to learn; +is Open. +These are some of the reasons people who use Python would rather not use anything else. + +Python can be easy to pick up whether you're a first time programmer +or you're experienced with other languages. +The following pages are a useful first step to get on your way +writing programs with Python! + +The community hosts conferences and meetups, collaborates on code, +and much more. Python's documentation will help you along the way, +and the mailing lists will keep you in touch. + +Conferences and Workshops +Python Documentation +Mailing Lists and IRC channels \ No newline at end of file diff --git a/source/c01/p03_keep_last_n_items.rst b/source/c01/p03_keep_last_n_items.rst index bad49b1..5e46259 100644 --- a/source/c01/p03_keep_last_n_items.rst +++ b/source/c01/p03_keep_last_n_items.rst @@ -5,14 +5,88 @@ ---------- 问题 ---------- -todo... +在迭代操作或者其他操作的时候,你只想保留最后有限几个元素的历史记录。 ---------- 解决方案 ---------- -todo... +保留有限历史记录正是collections.deque大显身手的时候。比如,下面的代码在多行上面做简单的文本匹配, +并只返回在前N行中匹配成功的行: + +.. code-block:: python + + from collections import deque + + + def search(lines, pattern, history=5): + previous_lines = deque(maxlen=history) + for li in lines: + if pattern in li: + yield li, 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) ---------- 讨论 ---------- -todo... +我们在写查询元素的代码的时候,通常会使用包含yield表达式的生成器函数,也就是我们上面示例代码中的那样。 +这样可以将搜索过程代码和使用搜索结果代码解耦。如果你还不清楚什么是生成器,请参看4.3节。 + +Using deque(maxlen=N) creates a fixed-sized queue. When new items are added and +the queue is full, the oldest item is automatically removed. For example: +使用deque(maxlen=N)构造函数会新建一个固定大小的队列。当心的元素加入并且这个队列已满的时候, +最老的元素会自动被移除掉。 + +代码示例: + +.. code-block:: python + + >>> 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类可以被用在任何你只需要一个简单队列数据结构的场合。 +如果你不设置最大队列大小,那么就会得到一个无限大小队列,你可以在队列的两端执行添加和弹出元素的操作。 + +代码示例: + +.. code-block:: python + + >>> 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),而在list的开头插入或删除元素的时间复杂度为O(N)。 +