mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 06:55:36 +08:00
316 lines
140 KiB
HTML
316 lines
140 KiB
HTML
<div class="body" role="main"><div class="section" id="module-collections"><h1><span class="yiyi-st" id="yiyi-10">8.3. <a class="reference internal" href="#module-collections" title="collections: Container datatypes"><code class="xref py py-mod docutils literal"><span class="pre">collections</span></code></a> — 容器数据类型</span></h1><p><span class="yiyi-st" id="yiyi-11"><strong>源代码:</strong> <a class="reference external" href="https://hg.python.org/cpython/file/3.5/Lib/collections/__init__.py">Lib/collections/__init__.py</a></span></p><p><span class="yiyi-st" id="yiyi-12">这个模块实现了专业的容器数据类型用来替代Python的通用内置容器,<a class="reference internal" href="stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal"><span class="pre">字典</span></code></a>, <a class="reference internal" href="stdtypes.html#list" title="list"><code class="xref py py-class docutils literal"><span class="pre">列表</span></code></a>, <a class="reference internal" href="stdtypes.html#set" title="set"><code class="xref py py-class docutils literal"><span class="pre">集合</span></code></a>, 和 <a class="reference internal" href="stdtypes.html#tuple" title="tuple"><code class="xref py py-class docutils literal"><span class="pre">元组</span></code></a>.</span></p><table border="1" class="docutils"><tbody valign="top"><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-13"><a class="reference internal" href="#collections.namedtuple" title="collections.namedtuple"><code class="xref py py-func docutils literal"><span class="pre">namedtuple()</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-14">这是个工厂方法,生成有命名字段的tuple子类(译注: tuple中的元素可以用名字的方式来访问)</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-15"><a class="reference internal" href="#collections.deque" title="collections.deque"><code class="xref py py-class docutils literal"><span class="pre">deque</span></code></a>(双向队列)</span></td><td><span class="yiyi-st" id="yiyi-16">一个能在“队列”两端快速出队、入队的,类似于队列的(list-like)的容器 (译者注:就是双向队列)</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-17"><a class="reference internal" href="#collections.ChainMap" title="collections.ChainMap"><code class="xref py py-class docutils literal"><span class="pre">ChainMap</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-18">为多个映射创建单一视图的类字典类型 (译者注:模仿作用域搜索)</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-19"><a class="reference internal" href="#collections.Counter" title="collections.Counter"><code class="xref py py-class docutils literal"><span class="pre">Counter</span></code></a>(计数器)</span></td><td><span class="yiyi-st" id="yiyi-20">dict子类,用于计算可哈希对象的个数</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-21"><a class="reference internal" href="#collections.OrderedDict" title="collections.OrderedDict"><code class="xref py py-class docutils literal"><span class="pre">OrderedDict</span></code></a>(有序字典)</span></td><td><span class="yiyi-st" id="yiyi-22">dict 子类 记录着数据成员添加的顺序</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-23"><a class="reference internal" href="#collections.defaultdict" title="collections.defaultdict"><code class="xref py py-class docutils literal"><span class="pre">defaultdict</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-24">调用一个工厂函数来为dict的values缺失提供值</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-25"><a class="reference internal" href="#collections.UserDict" title="collections.UserDict"><code class="xref py py-class docutils literal"><span class="pre">UserDict</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-26">将字典包裹起来使得创建字典的子类更容易</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-27"><a class="reference internal" href="#collections.UserList" title="collections.UserList"><code class="xref py py-class docutils literal"><span class="pre">UserList</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-28">将列表对象包裹起来使得创建列表的子类更容易</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-29"><a class="reference internal" href="#collections.UserString" title="collections.UserString"><code class="xref py py-class docutils literal"><span class="pre">UserString</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-30">将字符串对象包裹起来使得创建字符串的子类更容易</span></td></tr></tbody></table><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-31"><span class="versionmodified">在版本3.3中更改:</span>已将<a class="reference internal" href="collections.abc.html#collections-abstract-base-classes"><span>容器抽象基类</span></a>移动到<a class="reference internal" href="collections.abc.html#module-collections.abc" title="collections.abc: Abstract base classes for containers"><code class="xref py py-mod docutils literal"><span class="pre">collections.abc</span></code></a>模块。</span><span class="yiyi-st" id="yiyi-32">为了向后兼容,它们在该模块中也是可见的。</span></p></div><div class="section" id="chainmap-objects"><h2><span class="yiyi-st" id="yiyi-33">8.3.1.</span><span class="yiyi-st" id="yiyi-34"><a class="reference internal" href="#collections.ChainMap" title="collections.ChainMap"><code class="xref py py-class docutils literal"><span class="pre">ChainMap</span></code></a>对象</span></h2><div class="versionadded"><p><span class="yiyi-st" id="yiyi-35"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div><p><span class="yiyi-st" id="yiyi-36"><a class="reference internal" href="#collections.ChainMap" title="collections.ChainMap"><code class="xref py py-class docutils literal"><span class="pre">ChainMap</span></code></a>类对象提供一个链接多个mappings的单一单元。</span><span class="yiyi-st" id="yiyi-37">它比创建一个新字典和运行 <a class="reference internal" href="stdtypes.html#dict.update" title="dict.update"><code class="xref py py-meth docutils literal"><span class="pre">update()</span></code></a>方法要快。</span></p><p><span class="yiyi-st" id="yiyi-38">ChainMap用于模仿内嵌作用域和作为模板</span></p><dl class="class"><dt id="collections.ChainMap"><span class="yiyi-st" id="yiyi-39"><em class="property">class </em><code class="descclassname">collections.</code><code class="descname">ChainMap</code><span class="sig-paren">(</span><em>*maps</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-40">一个 <a class="reference internal" href="#collections.ChainMap" title="collections.ChainMap"><code class="xref py py-class docutils literal"><span class="pre">ChainMap</span></code></a>组合多个字典或其它映射集创建一个单一且可更新的视图。</span><span class="yiyi-st" id="yiyi-41">如果没有指定 <em>maps</em> ,那么将会用一个空字典作为新chain里面的一个mapping</span></p><p><span class="yiyi-st" id="yiyi-42">基础的mappings被存储在一个列表当中。</span><span class="yiyi-st" id="yiyi-43">这个列表是公开的,可以用 <em>maps</em> 属性访问和更新。</span><span class="yiyi-st" id="yiyi-44">没有其它的情况。</span></p><p><span class="yiyi-st" id="yiyi-45">使用查找功能会在基础的mappings查找,直到一个key被找到(译者注:相当于通过LEGB法则搜索)。</span><span class="yiyi-st" id="yiyi-46">相比较而言,创建键值对,更新键值对,删除键值对,仅仅在第一个mapping里面进行(译者注:相当于local)。</span></p><p><span class="yiyi-st" id="yiyi-47">通过引用,基础的映射集组合成<a class="reference internal" href="#collections.ChainMap" title="collections.ChainMap"><code class="xref py py-class docutils literal"><span class="pre">ChainMap</span></code></a>。</span><span class="yiyi-st" id="yiyi-48">所以,如果基础映射集(mappings)里面的一个mapping被更新,则这些改变都会反映在<a class="reference internal" href="#collections.ChainMap" title="collections.ChainMap"><code class="xref py py-class docutils literal"><span class="pre">ChainMap</span></code></a>。</span></p><p><span class="yiyi-st" id="yiyi-49">在ChainMap中dict的所有方法都适用。</span><span class="yiyi-st" id="yiyi-50">另外,ChainMap还有一个<em>maps</em>属性,new_child(m=None)方法用于创建一个新的子空间,parents属性访问除第一个mapping以外的映射集。</span></p><dl class="attribute"><dt id="collections.ChainMap.maps"><span class="yiyi-st" id="yiyi-51"><code class="descname">maps</code> </span></dt><dd><p><span class="yiyi-st" id="yiyi-52">用户可更新的mappings列表(译者注:修改它,也会修改ChainMap())。</span><span class="yiyi-st" id="yiyi-53">此列表是有序的,从第一个mapping到最后一个mapping。</span><span class="yiyi-st" id="yiyi-54">此列表仅仅存储状态,并且可以通过改变一个mapping来修改这个列表。</span><span class="yiyi-st" id="yiyi-55">此列表应该总是至少包含一个mapping。</span></p></dd></dl><dl class="method"><dt id="collections.ChainMap.new_child"><span class="yiyi-st" id="yiyi-56"><code class="descname">new_child</code><span class="sig-paren">(</span><em>m=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-57">返回一个新的 <a class="reference internal" href="#collections.ChainMap" title="collections.ChainMap"><code class="xref py py-class docutils literal"><span class="pre">ChainMap</span></code></a>,它包含一个新的map和当前实例的所有maps。</span><span class="yiyi-st" id="yiyi-58">如果指定<code class="docutils literal"><span class="pre">m</span></code>参数,那么它会成为新maps列表里面的第一个map; 如果没有被给,那么将会使用空字典作为第一个map,所以调用<code class="docutils literal"><span class="pre">d.new_child()</span></code> 等价于: <code class="docutils literal"><span class="pre">ChainMap({},</span> <span class="pre">*d.maps)</span></code>.。</span><span class="yiyi-st" id="yiyi-59">此方法用于创建子空间,当子空间的值被更新将不会影响父mappings里面的任何值。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-60">在<span class="versionmodified">Changed in version 3.4中:</span>选项 <code class="docutils literal"><span class="pre">m</span></code>参数被增加。</span></p></div></dd></dl><dl class="attribute"><dt id="collections.ChainMap.parents"><span class="yiyi-st" id="yiyi-61"><code class="descname">parents</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-62">parents属性返回一个新的<a class="reference internal" href="#collections.ChainMap" title="collections.ChainMap"><code class="xref py py-class docutils literal"><span class="pre">ChainMap</span></code></a>,它包含当前实例的除第一个map的所有maps。</span><span class="yiyi-st" id="yiyi-63">这个可以用于在搜索中跳过第一个map。</span><span class="yiyi-st" id="yiyi-64">在 <a class="reference internal" href="../glossary.html#term-nested-scope"><span class="xref std std-term">内嵌作用域中</span></a>的使用与关键字 <a class="reference internal" href="../reference/simple_stmts.html#nonlocal"><code class="xref std std-keyword docutils literal"><span class="pre">nonlocal</span></code></a> 相似。</span><span class="yiyi-st" id="yiyi-65">这个用法与内建的<a class="reference internal" href="functions.html#super" title="super"><code class="xref py py-func docutils literal"><span class="pre">super()</span></code></a> 函数相似。</span><span class="yiyi-st" id="yiyi-66"><code class="docutils literal"><span class="pre">d.parents</span></code> 相当于: <code class="docutils literal"><span class="pre">ChainMap(*d.maps[1:])</span></code>.</span></p></dd></dl></dd></dl><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-67">请参见</span></p><ul class="last simple"><li><span class="yiyi-st" id="yiyi-68">Enthought <a class="reference external" href="https://github.com/enthought/codetools">CodeTools包</a>中的<a class="reference external" href="https://github.com/enthought/codetools/blob/4.0.0/codetools/contexts/multi_context.py">MultiContext类</a>具有支持写入链中任何映射的选项。</span></li><li><span class="yiyi-st" id="yiyi-69">Django的<a class="reference external" href="https://github.com/django/django/blob/master/django/template/context.py">上下文类</a>用于模板化是只读链接的映射。</span><span class="yiyi-st" id="yiyi-70">它还具有类似于<a class="reference internal" href="#collections.ChainMap.new_child" title="collections.ChainMap.new_child"><code class="xref py py-meth docutils literal"><span class="pre">new_child()</span></code></a>方法和<a class="reference internal" href="#collections.ChainMap.parents" title="collections.ChainMap.parents"><code class="xref py py-meth docutils literal"><span class="pre">parents()</span></code></a>属性的上下文推送和弹出功能。</span></li><li><span class="yiyi-st" id="yiyi-71"><a class="reference external" href="https://code.activestate.com/recipes/577434/">嵌套上下文配方</a>具有控制写入和其他突变是否仅应用于链中的第一个映射或任何映射的选项。</span></li><li><span class="yiyi-st" id="yiyi-72"><a class="reference external" href="https://code.activestate.com/recipes/305268/">极大地简化了Chainmap</a>的只读版本。</span></li></ul></div><div class="section" id="chainmap-examples-and-recipes"><h3><span class="yiyi-st" id="yiyi-73">8.3.1.1.</span><span class="yiyi-st" id="yiyi-74"><a class="reference internal" href="#collections.ChainMap" title="collections.ChainMap"><code class="xref py py-class docutils literal"><span class="pre">ChainMap</span></code></a>示例和配方</span></h3><p><span class="yiyi-st" id="yiyi-75">此部分展示不同的ChainMap的用法。</span></p><p><span class="yiyi-st" id="yiyi-76">模仿python内部查找作用域链的例子:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">builtins</span>
|
||
<span class="n">pylookup</span> <span class="o">=</span> <span class="n">ChainMap</span><span class="p">(</span><span class="nb">locals</span><span class="p">(),</span> <span class="nb">globals</span><span class="p">(),</span> <span class="nb">vars</span><span class="p">(</span><span class="n">builtins</span><span class="p">))</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-77">让用户指定的命令行参数优先于环境变量的示例,这些环境变量的优先级高于默认值:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">argparse</span>
|
||
|
||
<span class="n">defaults</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'color'</span><span class="p">:</span> <span class="s1">'red'</span><span class="p">,</span> <span class="s1">'user'</span><span class="p">:</span> <span class="s1">'guest'</span><span class="p">}</span>
|
||
|
||
<span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">()</span>
|
||
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s1">'-u'</span><span class="p">,</span> <span class="s1">'--user'</span><span class="p">)</span>
|
||
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s1">'-c'</span><span class="p">,</span> <span class="s1">'--color'</span><span class="p">)</span>
|
||
<span class="n">namespace</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span>
|
||
<span class="n">command_line_args</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span><span class="n">v</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="nb">vars</span><span class="p">(</span><span class="n">namespace</span><span class="p">)</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">v</span><span class="p">}</span>
|
||
|
||
<span class="n">combined</span> <span class="o">=</span> <span class="n">ChainMap</span><span class="p">(</span><span class="n">command_line_args</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">,</span> <span class="n">defaults</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">combined</span><span class="p">[</span><span class="s1">'color'</span><span class="p">])</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">combined</span><span class="p">[</span><span class="s1">'user'</span><span class="p">])</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-78">使用<a class="reference internal" href="#collections.ChainMap" title="collections.ChainMap"><code class="xref py py-class docutils literal"><span class="pre">ChainMap</span></code></a>模仿内嵌空间的例子:</span></p><pre><code class="language-python"><span></span><span class="n">c</span> <span class="o">=</span> <span class="n">ChainMap</span><span class="p">()</span> <span class="c1"># Create root context</span>
|
||
<span class="n">d</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="n">new_child</span><span class="p">()</span> <span class="c1"># Create nested child context</span>
|
||
<span class="n">e</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="n">new_child</span><span class="p">()</span> <span class="c1"># Child of c, independent from d</span>
|
||
<span class="n">e</span><span class="o">.</span><span class="n">maps</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># Current context dictionary -- like Python's locals()</span>
|
||
<span class="n">e</span><span class="o">.</span><span class="n">maps</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="c1"># Root context -- like Python's globals()</span>
|
||
<span class="n">e</span><span class="o">.</span><span class="n">parents</span> <span class="c1"># Enclosing context chain -- like Python's nonlocals</span>
|
||
|
||
<span class="n">d</span><span class="p">[</span><span class="s1">'x'</span><span class="p">]</span> <span class="c1"># Get first key in the chain of contexts</span>
|
||
<span class="n">d</span><span class="p">[</span><span class="s1">'x'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1"># Set value in current context</span>
|
||
<span class="k">del</span> <span class="n">d</span><span class="p">[</span><span class="s1">'x'</span><span class="p">]</span> <span class="c1"># Delete from current context</span>
|
||
<span class="nb">list</span><span class="p">(</span><span class="n">d</span><span class="p">)</span> <span class="c1"># All nested values</span>
|
||
<span class="n">k</span> <span class="ow">in</span> <span class="n">d</span> <span class="c1"># Check all nested values</span>
|
||
<span class="nb">len</span><span class="p">(</span><span class="n">d</span><span class="p">)</span> <span class="c1"># Number of nested values</span>
|
||
<span class="n">d</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="c1"># All nested items</span>
|
||
<span class="nb">dict</span><span class="p">(</span><span class="n">d</span><span class="p">)</span> <span class="c1"># Flatten into a regular dictionary</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-79">当通过搜索整个链时(不是特定某个mapping),<a class="reference internal" href="#collections.ChainMap" title="collections.ChainMap"><code class="xref py py-class docutils literal"><span class="pre">ChainMap</span></code></a> 类仅仅只能更新,添加,删除第一个mapping(相当于locale)里面的键值对。</span><span class="yiyi-st" id="yiyi-80">然而,如果需要操作后面的mapping(相当于global),可以很容易通过创建一个子类来更新后面的mapping:</span></p><pre><code class="language-python"><span></span><span class="k">class</span> <span class="nc">DeepChainMap</span><span class="p">(</span><span class="n">ChainMap</span><span class="p">):</span>
|
||
<span class="s1">'Variant of ChainMap that allows direct updates to inner scopes'</span>
|
||
|
||
<span class="k">def</span> <span class="nf">__setitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
||
<span class="k">for</span> <span class="n">mapping</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">maps</span><span class="p">:</span>
|
||
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">mapping</span><span class="p">:</span>
|
||
<span class="n">mapping</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
||
<span class="k">return</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">maps</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
||
|
||
<span class="k">def</span> <span class="nf">__delitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
|
||
<span class="k">for</span> <span class="n">mapping</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">maps</span><span class="p">:</span>
|
||
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">mapping</span><span class="p">:</span>
|
||
<span class="k">del</span> <span class="n">mapping</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
||
<span class="k">return</span>
|
||
<span class="k">raise</span> <span class="ne">KeyError</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
|
||
|
||
<span class="o">>>></span> <span class="n">d</span> <span class="o">=</span> <span class="n">DeepChainMap</span><span class="p">({</span><span class="s1">'zebra'</span><span class="p">:</span> <span class="s1">'black'</span><span class="p">},</span> <span class="p">{</span><span class="s1">'elephant'</span><span class="p">:</span> <span class="s1">'blue'</span><span class="p">},</span> <span class="p">{</span><span class="s1">'lion'</span><span class="p">:</span> <span class="s1">'yellow'</span><span class="p">})</span>
|
||
<span class="o">>>></span> <span class="n">d</span><span class="p">[</span><span class="s1">'lion'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'orange'</span> <span class="c1"># update an existing key two levels down</span>
|
||
<span class="o">>>></span> <span class="n">d</span><span class="p">[</span><span class="s1">'snake'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'red'</span> <span class="c1"># new keys get added to the topmost dict</span>
|
||
<span class="o">>>></span> <span class="k">del</span> <span class="n">d</span><span class="p">[</span><span class="s1">'elephant'</span><span class="p">]</span> <span class="c1"># remove an existing key one level down</span>
|
||
<span class="n">DeepChainMap</span><span class="p">({</span><span class="s1">'zebra'</span><span class="p">:</span> <span class="s1">'black'</span><span class="p">,</span> <span class="s1">'snake'</span><span class="p">:</span> <span class="s1">'red'</span><span class="p">},</span> <span class="p">{},</span> <span class="p">{</span><span class="s1">'lion'</span><span class="p">:</span> <span class="s1">'orange'</span><span class="p">})</span>
|
||
</code></pre></div></div><div class="section" id="counter-objects"><h2><span class="yiyi-st" id="yiyi-81">8.3.2.</span><span class="yiyi-st" id="yiyi-82"><a class="reference internal" href="#collections.Counter" title="collections.Counter"><code class="xref py py-class docutils literal"><span class="pre">Counter</span></code></a>对象</span></h2><p><span class="yiyi-st" id="yiyi-83">计数器工具提供方面、快速的计数方法。</span><span class="yiyi-st" id="yiyi-84">示例:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="c1"># Tally occurrences of words in a list</span>
|
||
<span class="gp">>>> </span><span class="n">cnt</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">()</span>
|
||
<span class="gp">>>> </span><span class="k">for</span> <span class="n">word</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">'red'</span><span class="p">,</span> <span class="s1">'blue'</span><span class="p">,</span> <span class="s1">'red'</span><span class="p">,</span> <span class="s1">'green'</span><span class="p">,</span> <span class="s1">'blue'</span><span class="p">,</span> <span class="s1">'blue'</span><span class="p">]:</span>
|
||
<span class="gp">... </span> <span class="n">cnt</span><span class="p">[</span><span class="n">word</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
|
||
<span class="gp">>>> </span><span class="n">cnt</span>
|
||
<span class="go">Counter({'blue': 3, 'red': 2, 'green': 1})</span>
|
||
|
||
<span class="gp">>>> </span><span class="c1"># Find the ten most common words in Hamlet</span>
|
||
<span class="gp">>>> </span><span class="kn">import</span> <span class="nn">re</span>
|
||
<span class="gp">>>> </span><span class="n">words</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="s1">r'\w+'</span><span class="p">,</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'hamlet.txt'</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
|
||
<span class="gp">>>> </span><span class="n">Counter</span><span class="p">(</span><span class="n">words</span><span class="p">)</span><span class="o">.</span><span class="n">most_common</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
|
||
<span class="go">[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),</span>
|
||
<span class="go"> ('you', 554), ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]</span>
|
||
</code></pre><dl class="class"><dt id="collections.Counter"><span class="yiyi-st" id="yiyi-85"><em class="property">class </em><code class="descclassname">collections.</code><code class="descname">Counter</code><span class="sig-paren">(</span><span class="optional">[</span><em>iterable-or-mapping</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-86"><a class="reference internal" href="#collections.Counter" title="collections.Counter"><code class="xref py py-class docutils literal"><span class="pre">Counter</span></code></a>是<a class="reference internal" href="stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal"><span class="pre">dict</span></code></a>的子类,用于计数可哈希对象。</span><span class="yiyi-st" id="yiyi-87">它是一个无序的容器,元素被存储为字典键,它们的计数被存储为字典值。</span><span class="yiyi-st" id="yiyi-88">计数允许包括零或负计数的任何整数值。</span><span class="yiyi-st" id="yiyi-89"><a class="reference internal" href="#collections.Counter" title="collections.Counter"><code class="xref py py-class docutils literal"><span class="pre">Counter</span></code></a>类与其他语言的bags或multisets类似。</span></p><p><span class="yiyi-st" id="yiyi-90">它的元素从一个<em>可迭代对象</em>计数,或从另一个<em>映射</em>(或计数器)初始化:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">c</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">()</span> <span class="c1"># a new, empty counter</span>
|
||
<span class="gp">>>> </span><span class="n">c</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span><span class="s1">'gallahad'</span><span class="p">)</span> <span class="c1"># a new counter from an iterable</span>
|
||
<span class="gp">>>> </span><span class="n">c</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">({</span><span class="s1">'red'</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="s1">'blue'</span><span class="p">:</span> <span class="mi">2</span><span class="p">})</span> <span class="c1"># a new counter from a mapping</span>
|
||
<span class="gp">>>> </span><span class="n">c</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span><span class="n">cats</span><span class="o">=</span><span class="mi">4</span><span class="p">,</span> <span class="n">dogs</span><span class="o">=</span><span class="mi">8</span><span class="p">)</span> <span class="c1"># a new counter from keyword args</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-91">计数器对象的接口和字典一样,除了它们对于缺失项目返回一个零计数,而不是引发<a class="reference internal" href="exceptions.html#KeyError" title="KeyError"><code class="xref py py-exc docutils literal"><span class="pre">KeyError</span></code></a>:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">c</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">([</span><span class="s1">'eggs'</span><span class="p">,</span> <span class="s1">'ham'</span><span class="p">])</span>
|
||
<span class="gp">>>> </span><span class="n">c</span><span class="p">[</span><span class="s1">'bacon'</span><span class="p">]</span> <span class="c1"># count of a missing element is zero</span>
|
||
<span class="go">0</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-92">将计数设置为零不会从计数器中删除元素。</span><span class="yiyi-st" id="yiyi-93">使用<code class="docutils literal"><span class="pre">del</span></code>将其完全删除:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">c</span><span class="p">[</span><span class="s1">'sausage'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># counter entry with a zero count</span>
|
||
<span class="gp">>>> </span><span class="k">del</span> <span class="n">c</span><span class="p">[</span><span class="s1">'sausage'</span><span class="p">]</span> <span class="c1"># del actually removes the entry</span>
|
||
</code></pre><div class="versionadded"><p><span class="yiyi-st" id="yiyi-94"><span class="versionmodified">版本3.1中的新功能。</span></span></p></div><p><span class="yiyi-st" id="yiyi-95">计数器对象支持除了对所有字典可用的方法之外的三种方法:</span></p><dl class="method"><dt id="collections.Counter.elements"><span class="yiyi-st" id="yiyi-96"><code class="descname">elements</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-97">返回一个迭代器,对元素重复迭代其计数次。</span><span class="yiyi-st" id="yiyi-98">元素以随机顺序返回。</span><span class="yiyi-st" id="yiyi-99">如果元素的计数小于1,<a class="reference internal" href="#collections.Counter.elements" title="collections.Counter.elements"><code class="xref py py-meth docutils literal"><span class="pre">elements()</span></code></a>将忽略它。</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">c</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">4</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">d</span><span class="o">=-</span><span class="mi">2</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="nb">sorted</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">elements</span><span class="p">())</span>
|
||
<span class="go">['a', 'a', 'a', 'a', 'b', 'b']</span>
|
||
</code></pre></dd></dl><dl class="method"><dt id="collections.Counter.most_common"><span class="yiyi-st" id="yiyi-100"><code class="descname">most_common</code><span class="sig-paren">(</span><span class="optional">[</span><em>n</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-101">返回<em>n</em>个最常见的元素及其计数的列表,从最常见到最少见。</span><span class="yiyi-st" id="yiyi-102">如果省略<em>n</em>或为<code class="docutils literal"><span class="pre">None</span></code>,<a class="reference internal" href="#collections.Counter.most_common" title="collections.Counter.most_common"><code class="xref py py-func docutils literal"><span class="pre">most_common()</span></code></a>返回计数器中<em>所有</em>元素。</span><span class="yiyi-st" id="yiyi-103">具有相等计数的元素是任意排序的:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">Counter</span><span class="p">(</span><span class="s1">'abracadabra'</span><span class="p">)</span><span class="o">.</span><span class="n">most_common</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
|
||
<span class="go">[('a', 5), ('r', 2), ('b', 2)]</span>
|
||
</code></pre></dd></dl><dl class="method"><dt id="collections.Counter.subtract"><span class="yiyi-st" id="yiyi-104"><code class="descname">subtract</code><span class="sig-paren">(</span><span class="optional">[</span><em>iterable-or-mapping</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-105">从一个<em>可迭代对象</em>或从另一个<em>映射</em>(或计数器)中减去元素。</span><span class="yiyi-st" id="yiyi-106">类似<a class="reference internal" href="stdtypes.html#dict.update" title="dict.update"><code class="xref py py-meth docutils literal"><span class="pre">dict.update()</span></code></a>,但减去计数,而不是替换它们。</span><span class="yiyi-st" id="yiyi-107">输入和输出都可以为零或负。</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">c</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">4</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">d</span><span class="o">=-</span><span class="mi">2</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">subtract</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">c</span>
|
||
<span class="go">Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})</span>
|
||
</code></pre><div class="versionadded"><p><span class="yiyi-st" id="yiyi-108"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div></dd></dl><p><span class="yiyi-st" id="yiyi-109">除了两个字典方法对计数器工作不同,通常的都适用于<a class="reference internal" href="#collections.Counter" title="collections.Counter"><code class="xref py py-class docutils literal"><span class="pre">Counter</span></code></a>对象。</span></p><dl class="method"><dt id="collections.Counter.fromkeys"><span class="yiyi-st" id="yiyi-110"><code class="descname">fromkeys</code><span class="sig-paren">(</span><em>iterable</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-111">这个类方法未针对<a class="reference internal" href="#collections.Counter" title="collections.Counter"><code class="xref py py-class docutils literal"><span class="pre">Counter</span></code></a>对象实现。</span></p></dd></dl><dl class="method"><dt id="collections.Counter.update"><span class="yiyi-st" id="yiyi-112"><code class="descname">update</code><span class="sig-paren">(</span><span class="optional">[</span><em>iterable-or-mapping</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-113">元素从一个<em>可迭代对象</em>计数或从另一个<em>映射</em>(或计数器)增加。</span><span class="yiyi-st" id="yiyi-114">类似<a class="reference internal" href="stdtypes.html#dict.update" title="dict.update"><code class="xref py py-meth docutils literal"><span class="pre">dict.update()</span></code></a>,但增加计数,而不是替换它们。</span><span class="yiyi-st" id="yiyi-115">此外,<em>可迭代对象</em>应为一系列元素,而不是<code class="docutils literal"><span class="pre">(key,</span> <span class="pre">value)</span></code>对。</span></p></dd></dl></dd></dl><p><span class="yiyi-st" id="yiyi-116">使用<a class="reference internal" href="#collections.Counter" title="collections.Counter"><code class="xref py py-class docutils literal"><span class="pre">计数器</span></code></a>对象的常见模式:</span></p><pre><code class="language-python"><span></span><span class="nb">sum</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">values</span><span class="p">())</span> <span class="c1"># total of all counts</span>
|
||
<span class="n">c</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span> <span class="c1"># reset all counts</span>
|
||
<span class="nb">list</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="c1"># list unique elements</span>
|
||
<span class="nb">set</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="c1"># convert to a set</span>
|
||
<span class="nb">dict</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="c1"># convert to a regular dictionary</span>
|
||
<span class="n">c</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="c1"># convert to a list of (elem, cnt) pairs</span>
|
||
<span class="n">Counter</span><span class="p">(</span><span class="nb">dict</span><span class="p">(</span><span class="n">list_of_pairs</span><span class="p">))</span> <span class="c1"># convert from a list of (elem, cnt) pairs</span>
|
||
<span class="n">c</span><span class="o">.</span><span class="n">most_common</span><span class="p">()[:</span><span class="o">-</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="c1"># n least common elements</span>
|
||
<span class="o">+</span><span class="n">c</span> <span class="c1"># remove zero and negative counts</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-117">几个数学运算被提供以组合<a class="reference internal" href="#collections.Counter" title="collections.Counter"><code class="xref py py-class docutils literal"><span class="pre">Counter</span></code></a>对象来产生multisets(计数器大于零的计数器)。</span><span class="yiyi-st" id="yiyi-118">加法和减法通过相加或相减相应元素的计数来组合计数器。</span><span class="yiyi-st" id="yiyi-119">交集和并集返回相应计数的最小值和最大值。</span><span class="yiyi-st" id="yiyi-120">每个操作的输入都可以接受带有符号的计数,但输出将排除计数为零或更少的结果。</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">c</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">c</span> <span class="o">+</span> <span class="n">d</span> <span class="c1"># add two counters together: c[x] + d[x]</span>
|
||
<span class="go">Counter({'a': 4, 'b': 3})</span>
|
||
<span class="gp">>>> </span><span class="n">c</span> <span class="o">-</span> <span class="n">d</span> <span class="c1"># subtract (keeping only positive counts)</span>
|
||
<span class="go">Counter({'a': 2})</span>
|
||
<span class="gp">>>> </span><span class="n">c</span> <span class="o">&</span> <span class="n">d</span> <span class="c1"># intersection: min(c[x], d[x]) </span>
|
||
<span class="go">Counter({'a': 1, 'b': 1})</span>
|
||
<span class="gp">>>> </span><span class="n">c</span> <span class="o">|</span> <span class="n">d</span> <span class="c1"># union: max(c[x], d[x])</span>
|
||
<span class="go">Counter({'a': 3, 'b': 2})</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-121">一元加法和减法是与空计数器相加或从空计数器减去的快捷方式。</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">c</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">b</span><span class="o">=-</span><span class="mi">4</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="o">+</span><span class="n">c</span>
|
||
<span class="go">Counter({'a': 2})</span>
|
||
<span class="gp">>>> </span><span class="o">-</span><span class="n">c</span>
|
||
<span class="go">Counter({'b': 4})</span>
|
||
</code></pre><div class="versionadded"><p><span class="yiyi-st" id="yiyi-122"><span class="versionmodified">版本3.3中的新功能:</span>添加了对一元加号,一元减号和就地多元组操作的支持。</span></p></div><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-123">注意</span></p><p><span class="yiyi-st" id="yiyi-124">计数器主要设计为使用正整数表示运行计数;但是,需要注意不要不必要地排除需要其他类型或负值的用例。</span><span class="yiyi-st" id="yiyi-125">为了帮助这些用例,本节记录最小范围和类型限制。</span></p><ul class="last simple"><li><span class="yiyi-st" id="yiyi-126"><a class="reference internal" href="#collections.Counter" title="collections.Counter"><code class="xref py py-class docutils literal"><span class="pre">Counter</span></code></a>类本身是一个字典子类,对其键和值没有限制。</span><span class="yiyi-st" id="yiyi-127">这些值用于表示计数的数字,但你<em>可以</em>在值字段中存储任何内容。</span></li><li><span class="yiyi-st" id="yiyi-128"><code class="xref py py-meth docutils literal"><span class="pre">most_common()</span></code>方法只需要这些值是可排序的。</span></li><li><span class="yiyi-st" id="yiyi-129">对于诸如<code class="docutils literal"><span class="pre">c[key]</span> <span class="pre">+=</span> <span class="pre">1</span></code>之类的就地操作,值类型只需要支持加法和减法。</span><span class="yiyi-st" id="yiyi-130">因此,分数、浮点数和小数可以工作,支持负值。</span><span class="yiyi-st" id="yiyi-131">对于<code class="xref py py-meth docutils literal"><span class="pre">update()</span></code>和<code class="xref py py-meth docutils literal"><span class="pre">subtract()</span></code>也是如此,其允许输入和输出的负值和零值。</span></li><li><span class="yiyi-st" id="yiyi-132">Multiset方法仅用于具有正值的用例。</span><span class="yiyi-st" id="yiyi-133">输入可以是负或零,但是仅创建具有正值的输出。</span><span class="yiyi-st" id="yiyi-134">没有类型限制,但值类型需要支持加、减和比较。</span></li><li><span class="yiyi-st" id="yiyi-135"><code class="xref py py-meth docutils literal"><span class="pre">elements()</span></code>方法需要整数计数。</span><span class="yiyi-st" id="yiyi-136">它忽略零和负计数。</span></li></ul></div><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-137">也可以看看</span></p><ul class="last"><li><p class="first"><span class="yiyi-st" id="yiyi-138">Smalltalk中的<a class="reference external" href="https://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html">Bag class</a>。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-139"><a class="reference external" href="https://en.wikipedia.org/wiki/Multiset">Multisets</a>的维基百科条目。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-140"><a class="reference external" href="http://www.java2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm">C++ multisets</a>教程与示例。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-141">对于multisets的数学运算及其用例,参见<em>Knuth,Donald。 The Art of Computer Programming Volume II,Section 4.6.3,Exercise 19</em>。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-142">要枚举给定元素集合上给定大小的所有不同多重集合,请参见<a class="reference internal" href="itertools.html#itertools.combinations_with_replacement" title="itertools.combinations_with_replacement"><code class="xref py py-func docutils literal"><span class="pre">itertools.combinations_with_replacement()</span></code></a>:</span></p><span class="yiyi-st" id="yiyi-143"> <blockquote> <div><p>map(Counter, combinations_with_replacement(‘ABC’, 2)) –> AA AB AC BB BC CC</p> </div></blockquote></span></li></ul></div></div><div class="section" id="deque-objects"><h2><span class="yiyi-st" id="yiyi-144">8.3.3. <a class="reference internal" href="#collections.deque" title="collections.deque"><code class="xref py py-class docutils literal"><span class="pre">deque</span></code></a>对象</span></h2><dl class="class"><dt id="collections.deque"><span class="yiyi-st" id="yiyi-145"> <em class="property">class </em><code class="descclassname">collections.</code><code class="descname">deque</code><span class="sig-paren">(</span><span class="optional">[</span><em>iterable</em><span class="optional">[</span>, <em>maxlen</em><span class="optional">]</span><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-146">返回一个由<em>迭代器</em>从左到右(使用<a class="reference internal" href="#collections.deque.append" title="collections.deque.append"><code class="xref py py-meth docutils literal"><span class="pre">append()</span></code></a>)初始化的双向队列.</span><span class="yiyi-st" id="yiyi-147">若未指定初始化的<em>迭代器</em>,返回的双向队列的长度为0</span></p><p><span class="yiyi-st" id="yiyi-148">双向队列(Deque)是栈和队列的一般化(deque发音和‘deck’一样,是‘double-ended queue’的缩写)。</span><span class="yiyi-st" id="yiyi-149">Deque是线程安全的。在队列两端添加(append)或弹出(pop)元素的复杂度大约是O(1),所以Deque的效率是很高的。</span></p><p><span class="yiyi-st" id="yiyi-150">尽管<a class="reference internal" href="stdtypes.html#list" title="list"><code class="xref py py-class docutils literal"><span class="pre">list</span></code></a> 对象支持类似的操作, 但是list是专门为固定长度的操作进行了优化,导致了改变列表长度和数据位置的操作例如 <code class="docutils literal"><span class="pre">pop(0)</span></code>和 <code class="docutils literal"><span class="pre">insert(0,</span> <span class="pre">v)</span></code> 操作的复杂度高达O(n)</span></p><p><span class="yiyi-st" id="yiyi-151">如果 <em>maxlen</em> 未指定或为 <em>None</em>,deque可能长到任意长度。</span><span class="yiyi-st" id="yiyi-152">否则,deque的最大长度为指定的maxlen。</span><span class="yiyi-st" id="yiyi-153">一旦有界的双向队列满了以后,当有新的元素添加到队列中,就会有相应数量的元素在另一端被丢弃。</span><span class="yiyi-st" id="yiyi-154">有界双向队列提供了类似于Unix中<code class="docutils literal"><span class="pre">tail</span></code>过滤器的功能。</span><span class="yiyi-st" id="yiyi-155">They are also useful for tracking transactions and other pools of data where only the most recent activity is of interest.(译者:只能意会,翻译不了T_T)</span></p><p><span class="yiyi-st" id="yiyi-156">双向队列的对象支持一下方法:</span></p><dl class="method"><dt id="collections.deque.append"><span class="yiyi-st" id="yiyi-157"><code class="descname">append</code><span class="sig-paren">(</span><em>x</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-158"><em>x</em> 从右端入队.</span></p></dd></dl><dl class="method"><dt id="collections.deque.appendleft"><span class="yiyi-st" id="yiyi-159"><code class="descname">appendleft</code><span class="sig-paren">(</span><em>x</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-160"><em>x</em> 从左端入队.</span></p></dd></dl><dl class="method"><dt id="collections.deque.clear"><span class="yiyi-st" id="yiyi-161"><code class="descname">clear</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-162">清空队列中的所有元素,deque的长度变为0.</span></p></dd></dl><dl class="method"><dt id="collections.deque.copy"><span class="yiyi-st" id="yiyi-163"><code class="descname">copy</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-164">对deque进行浅复制.</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-165"><span class="versionmodified">版本3.5中的新功能。</span></span></p></div></dd></dl><dl class="method"><dt id="collections.deque.count"><span class="yiyi-st" id="yiyi-166"><code class="descname">count</code><span class="sig-paren">(</span><em>x</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-167">计算deque中值等于 <em>x</em> 的个数.</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-168"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div></dd></dl><dl class="method"><dt id="collections.deque.extend"><span class="yiyi-st" id="yiyi-169"><code class="descname">extend</code><span class="sig-paren">(</span><em>iterable</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-170">往deque的右端添加迭代器的元素</span></p></dd></dl><dl class="method"><dt id="collections.deque.extendleft"><span class="yiyi-st" id="yiyi-171"><code class="descname">extendleft</code><span class="sig-paren">(</span><em>iterable</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-172">通过将附加元素从扩展 deque 的左侧<em>可迭代</em>。</span><span class="yiyi-st" id="yiyi-173">请注意,左边的一系列附加结果在扭转可迭代参数中元素的顺序。</span></p></dd></dl><dl class="method"><dt id="collections.deque.index"><span class="yiyi-st" id="yiyi-174"><code class="descname">index</code><span class="sig-paren">(</span><em>x</em><span class="optional">[</span>, <em>start</em><span class="optional">[</span>, <em>stop</em><span class="optional">]</span><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-175">在deque中返回<em>x</em>的位置(在索引<em>开始</em>之后或索引<em>停止</em>之前)。</span><span class="yiyi-st" id="yiyi-176">如果未找到,则返回第一个匹配或引发<a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal"><span class="pre">ValueError</span></code></a>。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-177"><span class="versionmodified">版本3.5中的新功能。</span></span></p></div></dd></dl><dl class="method"><dt id="collections.deque.insert"><span class="yiyi-st" id="yiyi-178"><code class="descname">insert</code><span class="sig-paren">(</span><em>i</em>, <em>x</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-179">将<em>x</em>插入到位置<em>i</em>的deque中。</span></p><p><span class="yiyi-st" id="yiyi-180">如果插入将导致有界deque增长超过<em>maxlen</em>,则会引发<a class="reference internal" href="exceptions.html#IndexError" title="IndexError"><code class="xref py py-exc docutils literal"><span class="pre">IndexError</span></code></a>。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-181"><span class="versionmodified">版本3.5中的新功能。</span></span></p></div></dd></dl><dl class="method"><dt id="collections.deque.pop"><span class="yiyi-st" id="yiyi-182"><code class="descname">pop</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-183">删除并从右侧的双端队列中返回的元素。</span><span class="yiyi-st" id="yiyi-184">如果没有元素,则引入<a class="reference internal" href="exceptions.html#IndexError" title="IndexError"><code class="xref py py-exc docutils literal"><span class="pre">IndexError</span></code></a>。</span></p></dd></dl><dl class="method"><dt id="collections.deque.popleft"><span class="yiyi-st" id="yiyi-185"><code class="descname">popleft</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-186">移除并返回一个元素从 deque 的左侧。</span><span class="yiyi-st" id="yiyi-187">如果没有元素,则引入<a class="reference internal" href="exceptions.html#IndexError" title="IndexError"><code class="xref py py-exc docutils literal"><span class="pre">IndexError</span></code></a>。</span></p></dd></dl><dl class="method"><dt id="collections.deque.remove"><span class="yiyi-st" id="yiyi-188"><code class="descname">remove</code><span class="sig-paren">(</span><em>value</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-189">删除<em>值</em>的第一次出现。</span><span class="yiyi-st" id="yiyi-190">如果未找到,请引发<a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal"><span class="pre">ValueError</span></code></a>。</span></p></dd></dl><dl class="method"><dt id="collections.deque.reverse"><span class="yiyi-st" id="yiyi-191"><code class="descname">reverse</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-192">反转deque的元素,然后返回<code class="docutils literal"><span class="pre">None</span></code>。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-193"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div></dd></dl><dl class="method"><dt id="collections.deque.rotate"><span class="yiyi-st" id="yiyi-194"><code class="descname">rotate</code><span class="sig-paren">(</span><em>n</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-195">将deque向右旋转<em>n</em> 个元素。</span><span class="yiyi-st" id="yiyi-196">如果 <em>n</em> 是负数, 则向左旋转.</span><span class="yiyi-st" id="yiyi-197">向右旋转1个元素等价于<code class="docutils literal"><span class="pre">d.appendleft(d.pop())</span></code>.</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-198">Deque 对象还提供了一个只读属性:</span></p><dl class="attribute"><dt id="collections.deque.maxlen"><span class="yiyi-st" id="yiyi-199"><code class="descname">maxlen</code> </span></dt><dd><p><span class="yiyi-st" id="yiyi-200">Deque 的最大长度。如果没有边界,则返回<em>None</em>。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-201"><span class="versionmodified">版本3.1中的新功能。</span></span></p></div></dd></dl></dd></dl><p><span class="yiyi-st" id="yiyi-202">除了上述,deques支持迭代,pickle序列化,<code class="docutils literal"><span class="pre">len(d)</span></code>,<code class="docutils literal"><span class="pre">reversed(d)</span></code>,<code class="docutils literal"><span class="pre">copy.copy(d)</span></code> <code class="docutils literal"><span class="pre">copy.deepcopy(d)</span></code>,使用<a class="reference internal" href="../reference/expressions.html#in"><code class="xref std std-keyword docutils literal"><span class="pre">in</span></code></a>操作符号中的成员资格测试,以及诸如<code class="docutils literal"><span class="pre">d[-1]</span></code>的下标引用。</span><span class="yiyi-st" id="yiyi-203">索引的访问两端都是 o (1),但速度就减慢到 o (n) 在中间。</span><span class="yiyi-st" id="yiyi-204">对于快速的随机访问,改用列表。</span></p><p><span class="yiyi-st" id="yiyi-205">从版本3.5开始,deques支持<code class="docutils literal"><span class="pre">__add__()</span></code>,<code class="docutils literal"><span class="pre">__mul__()</span></code>和<code class="docutils literal"><span class="pre">__imul__()</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-206">示例:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">collections</span> <span class="k">import</span> <span class="n">deque</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">deque</span><span class="p">(</span><span class="s1">'ghi'</span><span class="p">)</span> <span class="c1"># make a new deque with three items</span>
|
||
<span class="gp">>>> </span><span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="n">d</span><span class="p">:</span> <span class="c1"># iterate over the deque's elements</span>
|
||
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="n">elem</span><span class="o">.</span><span class="n">upper</span><span class="p">())</span>
|
||
<span class="go">G</span>
|
||
<span class="go">H</span>
|
||
<span class="go">I</span>
|
||
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'j'</span><span class="p">)</span> <span class="c1"># add a new entry to the right side</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">appendleft</span><span class="p">(</span><span class="s1">'f'</span><span class="p">)</span> <span class="c1"># add a new entry to the left side</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="c1"># show the representation of the deque</span>
|
||
<span class="go">deque(['f', 'g', 'h', 'i', 'j'])</span>
|
||
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span> <span class="c1"># return and remove the rightmost item</span>
|
||
<span class="go">'j'</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">popleft</span><span class="p">()</span> <span class="c1"># return and remove the leftmost item</span>
|
||
<span class="go">'f'</span>
|
||
<span class="gp">>>> </span><span class="nb">list</span><span class="p">(</span><span class="n">d</span><span class="p">)</span> <span class="c1"># list the contents of the deque</span>
|
||
<span class="go">['g', 'h', 'i']</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># peek at leftmost item</span>
|
||
<span class="go">'g'</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="c1"># peek at rightmost item</span>
|
||
<span class="go">'i'</span>
|
||
|
||
<span class="gp">>>> </span><span class="nb">list</span><span class="p">(</span><span class="nb">reversed</span><span class="p">(</span><span class="n">d</span><span class="p">))</span> <span class="c1"># list the contents of a deque in reverse</span>
|
||
<span class="go">['i', 'h', 'g']</span>
|
||
<span class="gp">>>> </span><span class="s1">'h'</span> <span class="ow">in</span> <span class="n">d</span> <span class="c1"># search the deque</span>
|
||
<span class="go">True</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="s1">'jkl'</span><span class="p">)</span> <span class="c1"># add multiple elements at once</span>
|
||
<span class="gp">>>> </span><span class="n">d</span>
|
||
<span class="go">deque(['g', 'h', 'i', 'j', 'k', 'l'])</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">rotate</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># right rotation</span>
|
||
<span class="gp">>>> </span><span class="n">d</span>
|
||
<span class="go">deque(['l', 'g', 'h', 'i', 'j', 'k'])</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">rotate</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># left rotation</span>
|
||
<span class="gp">>>> </span><span class="n">d</span>
|
||
<span class="go">deque(['g', 'h', 'i', 'j', 'k', 'l'])</span>
|
||
|
||
<span class="gp">>>> </span><span class="n">deque</span><span class="p">(</span><span class="nb">reversed</span><span class="p">(</span><span class="n">d</span><span class="p">))</span> <span class="c1"># make a new deque in reverse order</span>
|
||
<span class="go">deque(['l', 'k', 'j', 'i', 'h', 'g'])</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span> <span class="c1"># empty the deque</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span> <span class="c1"># cannot pop from an empty deque</span>
|
||
<span class="gt">Traceback (most recent call last):</span>
|
||
<span class="n">File</span> <span class="s2">"<pyshell#6>"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">1</span><span class="p">,</span> <span class="ow">in</span> <span class="o">-</span><span class="n">toplevel</span><span class="o">-</span>
|
||
<span class="n">d</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
|
||
<span class="gr">IndexError</span>: <span class="n">pop from an empty deque</span>
|
||
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">extendleft</span><span class="p">(</span><span class="s1">'abc'</span><span class="p">)</span> <span class="c1"># extendleft() reverses the input order</span>
|
||
<span class="gp">>>> </span><span class="n">d</span>
|
||
<span class="go">deque(['c', 'b', 'a'])</span>
|
||
</code></pre><div class="section" id="deque-recipes"><h3><span class="yiyi-st" id="yiyi-207">8.3.3.1. <a class="reference internal" href="#collections.deque" title="collections.deque"><code class="xref py py-class docutils literal"><span class="pre">deque</span></code></a>使用方法 </span></h3><p><span class="yiyi-st" id="yiyi-208">本节将展示双端队列的各种处理方法</span></p><p><span class="yiyi-st" id="yiyi-209">边界长度deques提供类似于Unix中的<code class="docutils literal"><span class="pre">tail</span></code>过滤器的功能:</span></p><pre><code class="language-python"><span></span><span class="k">def</span> <span class="nf">tail</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">n</span><span class="o">=</span><span class="mi">10</span><span class="p">):</span>
|
||
<span class="s1">'Return the last n lines of a file'</span>
|
||
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="n">deque</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-210">使用通过另一种方法是通过追加向右和向左跳跳保持的最近添加的元素的序列:</span></p><pre><code class="language-python"><span></span><span class="k">def</span> <span class="nf">moving_average</span><span class="p">(</span><span class="n">iterable</span><span class="p">,</span> <span class="n">n</span><span class="o">=</span><span class="mi">3</span><span class="p">):</span>
|
||
<span class="c1"># moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0</span>
|
||
<span class="c1"># http://en.wikipedia.org/wiki/Moving_average</span>
|
||
<span class="n">it</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">iterable</span><span class="p">)</span>
|
||
<span class="n">d</span> <span class="o">=</span> <span class="n">deque</span><span class="p">(</span><span class="n">itertools</span><span class="o">.</span><span class="n">islice</span><span class="p">(</span><span class="n">it</span><span class="p">,</span> <span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">))</span>
|
||
<span class="n">d</span><span class="o">.</span><span class="n">appendleft</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
||
<span class="n">s</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
|
||
<span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="n">it</span><span class="p">:</span>
|
||
<span class="n">s</span> <span class="o">+=</span> <span class="n">elem</span> <span class="o">-</span> <span class="n">d</span><span class="o">.</span><span class="n">popleft</span><span class="p">()</span>
|
||
<span class="n">d</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">elem</span><span class="p">)</span>
|
||
<span class="k">yield</span> <span class="n">s</span> <span class="o">/</span> <span class="n">n</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-211"><code class="xref py py-meth docutils literal"><span class="pre">rotate()</span></code>方法提供了一种实现<a class="reference internal" href="#collections.deque" title="collections.deque"><code class="xref py py-class docutils literal"><span class="pre">deque</span></code></a>切片和删除的方法。</span><span class="yiyi-st" id="yiyi-212">例如,<code class="docutils literal"><span class="pre">del</span> <span class="pre">d [n]</span></code>的纯Python实现依赖于<code class="xref py py-meth docutils literal"><span class="pre">rotate()</span></code>要弹出的元素:</span></p><pre><code class="language-python"><span></span><span class="k">def</span> <span class="nf">delete_nth</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">n</span><span class="p">):</span>
|
||
<span class="n">d</span><span class="o">.</span><span class="n">rotate</span><span class="p">(</span><span class="o">-</span><span class="n">n</span><span class="p">)</span>
|
||
<span class="n">d</span><span class="o">.</span><span class="n">popleft</span><span class="p">()</span>
|
||
<span class="n">d</span><span class="o">.</span><span class="n">rotate</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-213">要实施<a class="reference internal" href="#collections.deque" title="collections.deque"><code class="xref py py-class docutils literal"><span class="pre">deque</span></code></a>切片,请使用类似的方法应用<code class="xref py py-meth docutils literal"><span class="pre">rotate()</span></code>将目标元素置于deque的左侧。</span><span class="yiyi-st" id="yiyi-214">使用<code class="xref py py-meth docutils literal"><span class="pre">popleft()</span></code>删除旧条目,使用<code class="xref py py-meth docutils literal"><span class="pre">extend()</span></code>添加新条目,然后反转旋转。</span><span class="yiyi-st" id="yiyi-215">With minor variations on that approach, it is easy to implement Forth style stack manipulations such as <code class="docutils literal"><span class="pre">dup</span></code>, <code class="docutils literal"><span class="pre">drop</span></code>, <code class="docutils literal"><span class="pre">swap</span></code>, <code class="docutils literal"><span class="pre">over</span></code>, <code class="docutils literal"><span class="pre">pick</span></code>, <code class="docutils literal"><span class="pre">rot</span></code>, and <code class="docutils literal"><span class="pre">roll</span></code>.</span></p></div></div><div class="section" id="defaultdict-objects"><h2><span class="yiyi-st" id="yiyi-216">8.3.4. <a class="reference internal" href="#collections.defaultdict" title="collections.defaultdict"><code class="xref py py-class docutils literal"><span class="pre">defaultdict</span></code></a>对象</span></h2><dl class="class"><dt id="collections.defaultdict"><span class="yiyi-st" id="yiyi-217"> <em class="property">class </em><code class="descclassname">collections.</code><code class="descname">defaultdict</code><span class="sig-paren">(</span><span class="optional">[</span><em>default_factory</em><span class="optional">[</span>, <em>...</em><span class="optional">]</span><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-218">返回一个新的类似字典的对象。</span><span class="yiyi-st" id="yiyi-219"><a class="reference internal" href="#collections.defaultdict" title="collections.defaultdict"><code class="xref py py-class docutils literal"><span class="pre">defaultdict</span></code></a>是内置<a class="reference internal" href="stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal"><span class="pre">dict</span></code></a>类的子类。</span><span class="yiyi-st" id="yiyi-220">它覆盖一个方法,并添加一个可写的实例变量。</span><span class="yiyi-st" id="yiyi-221">其余的功能与<a class="reference internal" href="stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal"><span class="pre">dict</span></code></a>类相同,这里就不再记录。</span></p><p><span class="yiyi-st" id="yiyi-222">第一个参数提供<a class="reference internal" href="#collections.defaultdict.default_factory" title="collections.defaultdict.default_factory"><code class="xref py py-attr docutils literal"><span class="pre">default_factory</span></code></a>属性的初始值;它默认为<code class="docutils literal"><span class="pre">None</span></code>。</span><span class="yiyi-st" id="yiyi-223">所有剩余的参数都视为与传递给<a class="reference internal" href="stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal"><span class="pre">dict</span></code></a>构造函数的参数相同,包括关键字参数。</span></p><p><span class="yiyi-st" id="yiyi-224"><a class="reference internal" href="#collections.defaultdict" title="collections.defaultdict"><code class="xref py py-class docutils literal"><span class="pre">defaultdict</span></code></a>对象除了支持标准的<a class="reference internal" href="stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal"><span class="pre">dict</span></code></a>操作,还支持以下方法:</span></p><dl class="method"><dt id="collections.defaultdict.__missing__"><span class="yiyi-st" id="yiyi-225"><code class="descname">__missing__</code> <span class="sig-paren">(</span> <em>key</em> <span class="sig-paren">)</span> </span></dt><dd><p><span class="yiyi-st" id="yiyi-226">如果<a class="reference internal" href="#collections.defaultdict.default_factory" title="collections.defaultdict.default_factory"><code class="xref py py-attr docutils literal"><span class="pre">default_factory</span></code></a>属性为<code class="docutils literal"><span class="pre">None</span></code>,则以<em>key</em>作为参数引发<a class="reference internal" href="exceptions.html#KeyError" title="KeyError"><code class="xref py py-exc docutils literal"><span class="pre">KeyError</span></code></a>异常。</span></p><p><span class="yiyi-st" id="yiyi-227">如果<a class="reference internal" href="#collections.defaultdict.default_factory" title="collections.defaultdict.default_factory"><code class="xref py py-attr docutils literal"><span class="pre">default_factory</span></code></a>不为<code class="docutils literal"><span class="pre">None</span></code>,则不带参数调用它以用来给<em>key</em>提供默认值,此值将插入到字典中用于<em>key</em>,并返回。</span></p><p><span class="yiyi-st" id="yiyi-228">如果调用<a class="reference internal" href="#collections.defaultdict.default_factory" title="collections.defaultdict.default_factory"><code class="xref py py-attr docutils literal"><span class="pre">default_factory</span></code></a>引发异常,则该异常会保持原样传播。</span></p><p><span class="yiyi-st" id="yiyi-229">当未找到请求的key时,此方法由<a class="reference internal" href="stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal"><span class="pre">dict</span></code></a>类的<a class="reference internal" href="../reference/datamodel.html#object.__getitem__" title="object.__getitem__"><code class="xref py py-meth docutils literal"><span class="pre">__getitem__()</span></code></a>方法调用;<a class="reference internal" href="../reference/datamodel.html#object.__getitem__" title="object.__getitem__"><code class="xref py py-meth docutils literal"><span class="pre">__getitem__()</span></code></a>将返回或引发它返回或引发的。</span></p><p><span class="yiyi-st" id="yiyi-230">请注意,除了<a class="reference internal" href="../reference/datamodel.html#object.__getitem__" title="object.__getitem__"><code class="xref py py-meth docutils literal"><span class="pre">__getitem__()</span></code></a>之外的任何操作,都<em>不</em>会调用<a class="reference internal" href="#collections.defaultdict.__missing__" title="collections.defaultdict.__missing__"><code class="xref py py-meth docutils literal"><span class="pre">__missing__()</span></code></a>。</span><span class="yiyi-st" id="yiyi-231">这意味着<code class="xref py py-meth docutils literal"><span class="pre">get()</span></code>会像正常的字典一样返回<code class="docutils literal"><span class="pre">None</span></code>作为默认值,而不是使用<a class="reference internal" href="#collections.defaultdict.default_factory" title="collections.defaultdict.default_factory"><code class="xref py py-attr docutils literal"><span class="pre">default_factory</span></code></a>。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-232"><a class="reference internal" href="#collections.defaultdict" title="collections.defaultdict"><code class="xref py py-class docutils literal"><span class="pre">defaultdict</span></code></a>对象支持以下实例变量:</span></p><dl class="attribute"><dt id="collections.defaultdict.default_factory"><span class="yiyi-st" id="yiyi-233"><code class="descname">default_factory</code> </span></dt><dd><p><span class="yiyi-st" id="yiyi-234">此属性由<a class="reference internal" href="#collections.defaultdict.__missing__" title="collections.defaultdict.__missing__"><code class="xref py py-meth docutils literal"><span class="pre">__missing__()</span></code></a>方法使用;如果构造函数的第一个参数存在,则初始化为它,如果不存在,则初始化为<code class="docutils literal"><span class="pre">None</span></code>。</span></p></dd></dl></dd></dl><div class="section" id="defaultdict-examples"><h3><span class="yiyi-st" id="yiyi-235">8.3.4.1. <a class="reference internal" href="#collections.defaultdict" title="collections.defaultdict"><code class="xref py py-class docutils literal"><span class="pre">defaultdict</span></code></a>示例</span></h3><p><span class="yiyi-st" id="yiyi-236">使用<a class="reference internal" href="stdtypes.html#list" title="list"><code class="xref py py-class docutils literal"><span class="pre">list</span></code></a>作为<code class="xref py py-attr docutils literal"><span class="pre">default_factory</span></code>,可以很容易地将一系列键值对分组为一个值为列表字典:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">s</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">'yellow'</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="s1">'blue'</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="s1">'yellow'</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="s1">'blue'</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="s1">'red'</span><span class="p">,</span> <span class="mi">1</span><span class="p">)]</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">list</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">s</span><span class="p">:</span>
|
||
<span class="gp">... </span> <span class="n">d</span><span class="p">[</span><span class="n">k</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
|
||
<span class="gp">...</span>
|
||
<span class="gp">>>> </span><span class="nb">sorted</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
|
||
<span class="go">[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-237">当每个键第一次遇到时,它不在映射中;因此使用返回空<a class="reference internal" href="stdtypes.html#list" title="list"><code class="xref py py-class docutils literal"><span class="pre">list</span></code></a>的<code class="xref py py-attr docutils literal"><span class="pre">default_factory</span></code>函数自动创建一个条目。</span><span class="yiyi-st" id="yiyi-238">然后,<code class="xref py py-meth docutils literal"><span class="pre">list.append()</span></code>操作将值附加到新列表。</span><span class="yiyi-st" id="yiyi-239">当再次遇到这个键时,查找正常继续(返回该键的列表),并且<code class="xref py py-meth docutils literal"><span class="pre">list.append()</span></code>操作向列表中添加另一个值。</span><span class="yiyi-st" id="yiyi-240">这种技术比使用等效的<a class="reference internal" href="stdtypes.html#dict.setdefault" title="dict.setdefault"><code class="xref py py-meth docutils literal"><span class="pre">dict.setdefault()</span></code></a>技术更简单和更快:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="p">{}</span>
|
||
<span class="gp">>>> </span><span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">s</span><span class="p">:</span>
|
||
<span class="gp">... </span> <span class="n">d</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
|
||
<span class="gp">...</span>
|
||
<span class="gp">>>> </span><span class="nb">sorted</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
|
||
<span class="go">[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-241">将<code class="xref py py-attr docutils literal"><span class="pre">default_factory</span></code>设置为<a class="reference internal" href="functions.html#int" title="int"><code class="xref py py-class docutils literal"><span class="pre">int</span></code></a>可使<a class="reference internal" href="#collections.defaultdict" title="collections.defaultdict"><code class="xref py py-class docutils literal"><span class="pre">defaultdict</span></code></a>用于计数(如其他语言的bag或multiset):</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">s</span> <span class="o">=</span> <span class="s1">'mississippi'</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">s</span><span class="p">:</span>
|
||
<span class="gp">... </span> <span class="n">d</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
|
||
<span class="gp">...</span>
|
||
<span class="gp">>>> </span><span class="nb">sorted</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
|
||
<span class="go">[('i', 4), ('m', 1), ('p', 2), ('s', 4)]</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-242">当一个字母第一次遇到时,映射中缺少该字母,因此<code class="xref py py-attr docutils literal"><span class="pre">default_factory</span></code>函数调用<a class="reference internal" href="functions.html#int" title="int"><code class="xref py py-func docutils literal"><span class="pre">int()</span></code></a>以提供默认计数零。</span><span class="yiyi-st" id="yiyi-243">后面,这个增量操作将建立每个字母的计数。</span></p><p><span class="yiyi-st" id="yiyi-244">始终返回零的函数<a class="reference internal" href="functions.html#int" title="int"><code class="xref py py-func docutils literal"><span class="pre">int()</span></code></a>只是常量函数的特殊情况。</span><span class="yiyi-st" id="yiyi-245">创建常量函数的更快和更灵活的方法是使用lambda函数,它可以提供任何常量值(不只是零):</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="k">def</span> <span class="nf">constant_factory</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
||
<span class="gp">... </span> <span class="k">return</span> <span class="k">lambda</span><span class="p">:</span> <span class="n">value</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="n">constant_factory</span><span class="p">(</span><span class="s1">'<missing>'</span><span class="p">))</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">'John'</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s1">'ran'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="s1">'</span><span class="si">%(name)s</span><span class="s1"> </span><span class="si">%(action)s</span><span class="s1"> to </span><span class="si">%(object)s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">d</span>
|
||
<span class="go">'John ran to <missing>'</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-246">将<code class="xref py py-attr docutils literal"><span class="pre">default_factory</span></code>设置为<a class="reference internal" href="stdtypes.html#set" title="set"><code class="xref py py-class docutils literal"><span class="pre">set</span></code></a>可使<a class="reference internal" href="#collections.defaultdict" title="collections.defaultdict"><code class="xref py py-class docutils literal"><span class="pre">defaultdict</span></code></a>有助于构建集合字典:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">s</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">'red'</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="s1">'blue'</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="s1">'red'</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="s1">'blue'</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="s1">'red'</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="s1">'blue'</span><span class="p">,</span> <span class="mi">4</span><span class="p">)]</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">set</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">s</span><span class="p">:</span>
|
||
<span class="gp">... </span> <span class="n">d</span><span class="p">[</span><span class="n">k</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
|
||
<span class="gp">...</span>
|
||
<span class="gp">>>> </span><span class="nb">sorted</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
|
||
<span class="go">[('blue', {2, 4}), ('red', {1, 3})]</span>
|
||
</code></pre></div></div><div class="section" id="namedtuple-factory-function-for-tuples-with-named-fields"><h2><span class="yiyi-st" id="yiyi-247">8.3.5. <a class="reference internal" href="#collections.namedtuple" title="collections.namedtuple"><code class="xref py py-func docutils literal"><span class="pre">namedtuple()</span></code></a>工厂函数,用于具有命名字段的元组</span></h2><p><span class="yiyi-st" id="yiyi-248">命名元组赋予元组中的每个位置一定的含义,允许更具可读性、自带文档的代码。</span><span class="yiyi-st" id="yiyi-249">它们可以用作常规元组可以使用的任何地方,并且它们添加能够按名称而不是位置索引字段的能力。</span></p><dl class="function"><dt id="collections.namedtuple"><span class="yiyi-st" id="yiyi-250"><code class="descclassname">collections.</code><code class="descname">namedtuple</code><span class="sig-paren">(</span><em>typename</em>, <em>field_names</em>, <em>verbose=False</em>, <em>rename=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-251">返回一个叫做<em>typename</em>的新的元组子类。</span><span class="yiyi-st" id="yiyi-252">这个新的子类用来创建类元组对象,这个对象拥有可以通过属性访问的字段,并且可以通过下标索引和迭代。</span><span class="yiyi-st" id="yiyi-253">这个子类的实例还拥有十分友好的文档字符串(包括类型名和字段名)和十分好用的<a class="reference internal" href="../reference/datamodel.html#object.__repr__" title="object.__repr__"><code class="xref py py-meth docutils literal"><span class="pre">__repr__()</span></code></a> 方法,以<code class="docutils literal"><span class="pre">name=value</span></code>的方式列出了元组中的内容。</span></p><p><span class="yiyi-st" id="yiyi-254"><em>field_names</em>是单个字符串,其中的每个字段用空格或逗号隔开,例如 <code class="docutils literal"><span class="pre">'x</span> <span class="pre">y'</span></code>或<code class="docutils literal"><span class="pre">'x,</span> <span class="pre">y'</span></code>。</span><span class="yiyi-st" id="yiyi-255">另外,<em>field_names</em>可以是字符串的列表,例如<code class="docutils literal"><span class="pre">['x',</span> <span class="pre">'y']</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-256">除了以下划线开头的名称,任何有效的 Python 标识符都可用于 fieldname 。</span><span class="yiyi-st" id="yiyi-257">有效的标识符由字母、 数字和下划线组成,但是不能以数字或下划线开头,并且不能是 <a class="reference internal" href="keyword.html#module-keyword" title="keyword: Test whether a string is a keyword in Python."><code class="xref py py-mod docutils literal"><span class="pre">关键字</span></code></a> 例如 <em>class</em>、 <em>for</em>、 <em>return</em>、 <em>global</em>、 <em>pass</em> 或 <em>raise</em>。</span></p><p><span class="yiyi-st" id="yiyi-258">如果 <em>rename参数</em> 为 True, 无效的字段名会被自动转换成位置的名称.</span><span class="yiyi-st" id="yiyi-259">例如, <code class="docutils literal"><span class="pre">['abc',</span> <span class="pre">'def',</span> <span class="pre">'ghi',</span> <span class="pre">'abc']</span></code> 将被转换为 <code class="docutils literal"><span class="pre">['abc',</span> <span class="pre">'_1',</span> <span class="pre">'ghi',</span> <span class="pre">'_3']</span></code>, 来消除关键字 <code class="docutils literal"><span class="pre">def</span></code> 和重复的字段名 <code class="docutils literal"><span class="pre">abc</span></code>.</span></p><p><span class="yiyi-st" id="yiyi-260">如果<em>verbose</em>为真,则在构建它后将打印这个类的定义。</span><span class="yiyi-st" id="yiyi-261">此选项已过时;相反,打印<code class="xref py py-attr docutils literal"><span class="pre">_source</span></code>属性更简单。</span></p><p><span class="yiyi-st" id="yiyi-262">命名元组没有在每个实例中包含一个字典, 所以它们是轻量级的,并不会比常规的元组消耗更多的内存。</span></p><p><span class="yiyi-st" id="yiyi-263">对于简单使用,其中唯一的要求是能够使用属性样式访问通过名称引用一组值,<a class="reference internal" href="types.html#types.SimpleNamespace" title="types.SimpleNamespace"><code class="xref py py-class docutils literal"><span class="pre">types.SimpleNamespace</span></code></a>类型可以是使用命名的元组的合适替代。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-264"><span class="versionmodified">在版本3.1中已更改:</span>添加了对<em>重命名</em>的支持。</span></p></div></dd></dl><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="c1"># Basic example</span>
|
||
<span class="gp">>>> </span><span class="n">Point</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'Point'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'x'</span><span class="p">,</span> <span class="s1">'y'</span><span class="p">])</span>
|
||
<span class="gp">>>> </span><span class="n">p</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="mi">22</span><span class="p">)</span> <span class="c1"># instantiate with positional or keyword arguments</span>
|
||
<span class="gp">>>> </span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="c1"># indexable like the plain tuple (11, 22)</span>
|
||
<span class="go">33</span>
|
||
<span class="gp">>>> </span><span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">p</span> <span class="c1"># unpack like a regular tuple</span>
|
||
<span class="gp">>>> </span><span class="n">x</span><span class="p">,</span> <span class="n">y</span>
|
||
<span class="go">(11, 22)</span>
|
||
<span class="gp">>>> </span><span class="n">p</span><span class="o">.</span><span class="n">x</span> <span class="o">+</span> <span class="n">p</span><span class="o">.</span><span class="n">y</span> <span class="c1"># fields also accessible by name</span>
|
||
<span class="go">33</span>
|
||
<span class="gp">>>> </span><span class="n">p</span> <span class="c1"># readable __repr__ with a name=value style</span>
|
||
<span class="go">Point(x=11, y=22)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-265">namedtuple 在为 <a class="reference internal" href="csv.html#module-csv" title="csv: Write and read tabular data to and from delimited files."><code class="xref py py-mod docutils literal"><span class="pre">csv</span></code></a> or <a class="reference internal" href="sqlite3.html#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal"><span class="pre">sqlite3</span></code></a> 模块返回的元组命名显得十分有用:</span></p><pre><code class="language-python"><span></span><span class="n">EmployeeRecord</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'EmployeeRecord'</span><span class="p">,</span> <span class="s1">'name, age, title, department, paygrade'</span><span class="p">)</span>
|
||
|
||
<span class="kn">import</span> <span class="nn">csv</span>
|
||
<span class="k">for</span> <span class="n">emp</span> <span class="ow">in</span> <span class="nb">map</span><span class="p">(</span><span class="n">EmployeeRecord</span><span class="o">.</span><span class="n">_make</span><span class="p">,</span> <span class="n">csv</span><span class="o">.</span><span class="n">reader</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s2">"employees.csv"</span><span class="p">,</span> <span class="s2">"rb"</span><span class="p">))):</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">emp</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">emp</span><span class="o">.</span><span class="n">title</span><span class="p">)</span>
|
||
|
||
<span class="kn">import</span> <span class="nn">sqlite3</span>
|
||
<span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s1">'/companydata'</span><span class="p">)</span>
|
||
<span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
|
||
<span class="n">cursor</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s1">'SELECT name, age, title, department, paygrade FROM employees'</span><span class="p">)</span>
|
||
<span class="k">for</span> <span class="n">emp</span> <span class="ow">in</span> <span class="nb">map</span><span class="p">(</span><span class="n">EmployeeRecord</span><span class="o">.</span><span class="n">_make</span><span class="p">,</span> <span class="n">cursor</span><span class="o">.</span><span class="n">fetchall</span><span class="p">()):</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">emp</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">emp</span><span class="o">.</span><span class="n">title</span><span class="p">)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-266">除了从tuple继承而来的方法,namedtuple还支持另外三个方法和两个属性。</span><span class="yiyi-st" id="yiyi-267">为了避免和字段冲突,这些方法和属性都以下划线开头</span></p><dl class="classmethod"><dt id="collections.somenamedtuple._make"><span class="yiyi-st" id="yiyi-268"><em class="property">classmethod </em><code class="descclassname">somenamedtuple.</code><code class="descname">_make</code><span class="sig-paren">(</span><em>iterable</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-269">类方法。从现有的列表或迭代器创建一个新的实例</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">t</span> <span class="o">=</span> <span class="p">[</span><span class="mi">11</span><span class="p">,</span> <span class="mi">22</span><span class="p">]</span>
|
||
<span class="gp">>>> </span><span class="n">Point</span><span class="o">.</span><span class="n">_make</span><span class="p">(</span><span class="n">t</span><span class="p">)</span>
|
||
<span class="go">Point(x=11, y=22)</span>
|
||
</code></pre></dd></dl><dl class="method"><dt id="collections.somenamedtuple._asdict"><span class="yiyi-st" id="yiyi-270"><code class="descclassname">somenamedtuple.</code><code class="descname">_asdict</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-271">返回一个<a class="reference internal" href="#collections.OrderedDict" title="collections.OrderedDict"><code class="xref py py-class docutils literal"><span class="pre">OrderedDict(有序字典)</span></code></a>,每个键对应于该字段的值</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">p</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">11</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="mi">22</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">p</span><span class="o">.</span><span class="n">_asdict</span><span class="p">()</span>
|
||
<span class="go">OrderedDict([('x', 11), ('y', 22)])</span>
|
||
</code></pre><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-272"><span class="versionmodified">在版本3.1中更改:</span>返回<a class="reference internal" href="#collections.OrderedDict" title="collections.OrderedDict"><code class="xref py py-class docutils literal"><span class="pre">OrderedDict</span></code></a>,而不是常规<a class="reference internal" href="stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal"><span class="pre">dict</span></code></a>。</span></p></div></dd></dl><dl class="method"><dt id="collections.somenamedtuple._replace"><span class="yiyi-st" id="yiyi-273"><code class="descclassname">somenamedtuple.</code><code class="descname">_replace</code><span class="sig-paren">(</span><em>kwargs</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-274">返回指定的字段替换为新值的命名的元组的一个新实例:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">p</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">11</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="mi">22</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">p</span><span class="o">.</span><span class="n">_replace</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">33</span><span class="p">)</span>
|
||
<span class="go">Point(x=33, y=22)</span>
|
||
|
||
<span class="gp">>>> </span><span class="k">for</span> <span class="n">partnum</span><span class="p">,</span> <span class="n">record</span> <span class="ow">in</span> <span class="n">inventory</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
||
<span class="gp">... </span> <span class="n">inventory</span><span class="p">[</span><span class="n">partnum</span><span class="p">]</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">_replace</span><span class="p">(</span><span class="n">price</span><span class="o">=</span><span class="n">newprices</span><span class="p">[</span><span class="n">partnum</span><span class="p">],</span> <span class="n">timestamp</span><span class="o">=</span><span class="n">time</span><span class="o">.</span><span class="n">now</span><span class="p">())</span>
|
||
</code></pre></dd></dl><dl class="attribute"><dt id="collections.somenamedtuple._source"><span class="yiyi-st" id="yiyi-275"><code class="descclassname">somenamedtuple.</code><code class="descname">_source</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-276">一个带有纯Python源代码的字符串,用于创建命名的tuple类。</span><span class="yiyi-st" id="yiyi-277">源使得命名的元组自我记录。</span><span class="yiyi-st" id="yiyi-278">它可以打印,使用<a class="reference internal" href="functions.html#exec" title="exec"><code class="xref py py-func docutils literal"><span class="pre">exec()</span></code></a>执行,或保存到文件并导入。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-279"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div></dd></dl><dl class="attribute"><dt id="collections.somenamedtuple._fields"><span class="yiyi-st" id="yiyi-280"><code class="descclassname">somenamedtuple.</code><code class="descname">_fields</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-281">字段名称的元组。</span><span class="yiyi-st" id="yiyi-282">在自我检查和从已有的namedtuple创建新的namedtuple非常有用。</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">p</span><span class="o">.</span><span class="n">_fields</span> <span class="c1"># view the field names</span>
|
||
<span class="go">('x', 'y')</span>
|
||
|
||
<span class="gp">>>> </span><span class="n">Color</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'Color'</span><span class="p">,</span> <span class="s1">'red green blue'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">Pixel</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'Pixel'</span><span class="p">,</span> <span class="n">Point</span><span class="o">.</span><span class="n">_fields</span> <span class="o">+</span> <span class="n">Color</span><span class="o">.</span><span class="n">_fields</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">Pixel</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span> <span class="mi">22</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="go">Pixel(x=11, y=22, red=128, green=255, blue=0)</span>
|
||
</code></pre></dd></dl><p><span class="yiyi-st" id="yiyi-283">要检索名称存储在字符串中的字段,请使用<a class="reference internal" href="functions.html#getattr" title="getattr"><code class="xref py py-func docutils literal"><span class="pre">getattr()</span></code></a>函数:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="nb">getattr</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="s1">'x'</span><span class="p">)</span>
|
||
<span class="go">11</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-284">要将字典转换为命名的元组,请使用双星运算符(如<a class="reference internal" href="../tutorial/controlflow.html#tut-unpacking-arguments"><span>Unpacking Argument Lists</span></a>中所述):</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'x'</span><span class="p">:</span> <span class="mi">11</span><span class="p">,</span> <span class="s1">'y'</span><span class="p">:</span> <span class="mi">22</span><span class="p">}</span>
|
||
<span class="gp">>>> </span><span class="n">Point</span><span class="p">(</span><span class="o">**</span><span class="n">d</span><span class="p">)</span>
|
||
<span class="go">Point(x=11, y=22)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-285">因为命名的元组是一个常规的 Python 类,很容易添加或更改它的子类的功能。</span><span class="yiyi-st" id="yiyi-286">下面介绍了如何添加一个计算的字段和固定宽度打印格式:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="k">class</span> <span class="nc">Point</span><span class="p">(</span><span class="n">namedtuple</span><span class="p">(</span><span class="s1">'Point'</span><span class="p">,</span> <span class="s1">'x y'</span><span class="p">)):</span>
|
||
<span class="gp">... </span> <span class="n">__slots__</span> <span class="o">=</span> <span class="p">()</span>
|
||
<span class="gp">... </span> <span class="nd">@property</span>
|
||
<span class="gp">... </span> <span class="k">def</span> <span class="nf">hypot</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="gp">... </span> <span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">**</span> <span class="mi">2</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">**</span> <span class="mi">2</span><span class="p">)</span> <span class="o">**</span> <span class="mf">0.5</span>
|
||
<span class="gp">... </span> <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="gp">... </span> <span class="k">return</span> <span class="s1">'Point: x=</span><span class="si">%6.3f</span><span class="s1"> y=</span><span class="si">%6.3f</span><span class="s1"> hypot=</span><span class="si">%6.3f</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">hypot</span><span class="p">)</span>
|
||
</code></pre><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">Point</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="n">Point</span><span class="p">(</span><span class="mi">14</span><span class="p">,</span> <span class="mi">5</span><span class="o">/</span><span class="mi">7</span><span class="p">):</span>
|
||
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
|
||
<span class="go">Point: x= 3.000 y= 4.000 hypot= 5.000</span>
|
||
<span class="go">Point: x=14.000 y= 0.714 hypot=14.018</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-287">上面显示的子类将<code class="docutils literal"><span class="pre">__slots__</span></code>设置为空元组。</span><span class="yiyi-st" id="yiyi-288">这有助于防止创建的实例字典通过保持内存需求低。</span></p><p><span class="yiyi-st" id="yiyi-289">子类化不是新的存储字段中添加有用的。</span><span class="yiyi-st" id="yiyi-290">相反,只需从<code class="xref py py-attr docutils literal"><span class="pre">_fields</span></code>属性创建一个新的命名元组类型:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">Point3D</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'Point3D'</span><span class="p">,</span> <span class="n">Point</span><span class="o">.</span><span class="n">_fields</span> <span class="o">+</span> <span class="p">(</span><span class="s1">'z'</span><span class="p">,))</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-291">可以通过对<code class="docutils literal"><span class="pre">__doc__</span></code>字段进行直接分配来自定义文档字符串:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">Book</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'Book'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'id'</span><span class="p">,</span> <span class="s1">'title'</span><span class="p">,</span> <span class="s1">'authors'</span><span class="p">])</span>
|
||
<span class="gp">>>> </span><span class="n">Book</span><span class="o">.</span><span class="n">__doc__</span> <span class="o">+=</span> <span class="s1">': Hardcover book in active collection'</span>
|
||
<span class="gp">>>> </span><span class="n">Book</span><span class="o">.</span><span class="n">id</span><span class="o">.</span><span class="n">__doc__</span> <span class="o">=</span> <span class="s1">'13-digit ISBN'</span>
|
||
<span class="gp">>>> </span><span class="n">Book</span><span class="o">.</span><span class="n">title</span><span class="o">.</span><span class="n">__doc__</span> <span class="o">=</span> <span class="s1">'Title of first printing'</span>
|
||
<span class="gp">>>> </span><span class="n">Book</span><span class="o">.</span><span class="n">authors</span><span class="o">.</span><span class="n">__doc__</span> <span class="o">=</span> <span class="s1">'List of authors sorted by last name'</span>
|
||
</code></pre><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-292"><span class="versionmodified">在3.5版本中已更改:</span>属性文档字符串变得可写。</span></p></div><p><span class="yiyi-st" id="yiyi-293">默认值可以通过使用<code class="xref py py-meth docutils literal"><span class="pre">_replace()</span></code>实现原型实例:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">Account</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'Account'</span><span class="p">,</span> <span class="s1">'owner balance transaction_count'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">default_account</span> <span class="o">=</span> <span class="n">Account</span><span class="p">(</span><span class="s1">'<owner name>'</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">johns_account</span> <span class="o">=</span> <span class="n">default_account</span><span class="o">.</span><span class="n">_replace</span><span class="p">(</span><span class="n">owner</span><span class="o">=</span><span class="s1">'John'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">janes_account</span> <span class="o">=</span> <span class="n">default_account</span><span class="o">.</span><span class="n">_replace</span><span class="p">(</span><span class="n">owner</span><span class="o">=</span><span class="s1">'Jane'</span><span class="p">)</span>
|
||
</code></pre><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-294">请参见</span></p><ul class="last simple"><li><span class="yiyi-st" id="yiyi-295"><a class="reference external" href="https://code.activestate.com/recipes/577629-namedtupleabc-abstract-base-class-mix-in-for-named/">由Jan Kaliszewski提供的具有元类混合的命名元组抽象基类的配方</a>。</span><span class="yiyi-st" id="yiyi-296">除了为命名元组提供<a class="reference internal" href="../glossary.html#term-abstract-base-class"><span class="xref std std-term">abstract base class</span></a>,它还支持一个替换的<a class="reference internal" href="../glossary.html#term-metaclass"><span class="xref std std-term">metaclass</span></a>构造函数,便于对命名元组进行子类化的用例。</span></li></ul></div></div><div class="section" id="ordereddict-objects"><h2><span class="yiyi-st" id="yiyi-297">8.3.6.</span><span class="yiyi-st" id="yiyi-298"><a class="reference internal" href="#collections.OrderedDict" title="collections.OrderedDict"><code class="xref py py-class docutils literal"><span class="pre">OrderedDict</span></code></a>对象</span></h2><p><span class="yiyi-st" id="yiyi-299">有序字典与常规字典类似,但它们记住项目插入的顺序。</span><span class="yiyi-st" id="yiyi-300">当对有序字典进行迭代时,项目按它们的键首次添加的顺序返回。</span></p><dl class="class"><dt id="collections.OrderedDict"><span class="yiyi-st" id="yiyi-301"> <em class="property">class </em><code class="descclassname">collections.</code><code class="descname">OrderedDict</code><span class="sig-paren">(</span><span class="optional">[</span><em>items</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-302">返回一个dict子类的实例,支持通常的<a class="reference internal" href="stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal"><span class="pre">dict</span></code></a>方法。</span><span class="yiyi-st" id="yiyi-303"><em>OrderedDict</em>是记住键首次插入顺序的字典。</span><span class="yiyi-st" id="yiyi-304">如果新条目覆盖现有条目,则原始插入位置保持不变。</span><span class="yiyi-st" id="yiyi-305">删除条目并重新插入会将其移动到末尾。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-306"><span class="versionmodified">版本3.1中的新功能。</span></span></p></div><dl class="method"><dt id="collections.OrderedDict.popitem"><span class="yiyi-st" id="yiyi-307"><code class="descname">popitem</code><span class="sig-paren">(</span><em>last=True</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-308">有序字典的<a class="reference internal" href="#collections.OrderedDict.popitem" title="collections.OrderedDict.popitem"><code class="xref py py-meth docutils literal"><span class="pre">popitem()</span></code></a>方法返回并删除(key, value)对。</span><span class="yiyi-st" id="yiyi-309">如果<em>last</em>为真,则以LIFO顺序返回这些键值对,如果为假,则以FIFO顺序返回。</span></p></dd></dl><dl class="method"><dt id="collections.OrderedDict.move_to_end"><span class="yiyi-st" id="yiyi-310"><code class="descname">move_to_end</code><span class="sig-paren">(</span><em>key</em>, <em>last=True</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-311">将一个已存在<em>key</em>移动到有序字典的任一端。</span><span class="yiyi-st" id="yiyi-312">如果<em>last</em>为真(默认值),则项目移动到末尾,如果<em>last</em>为假,则移动到开始。</span><span class="yiyi-st" id="yiyi-313">如果<em>key</em>不存在,引发<a class="reference internal" href="exceptions.html#KeyError" title="KeyError"><code class="xref py py-exc docutils literal"><span class="pre">KeyError</span></code></a>:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">OrderedDict</span><span class="o">.</span><span class="n">fromkeys</span><span class="p">(</span><span class="s1">'abcde'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">move_to_end</span><span class="p">(</span><span class="s1">'b'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
|
||
<span class="go">'acdeb'</span>
|
||
<span class="gp">>>> </span><span class="n">d</span><span class="o">.</span><span class="n">move_to_end</span><span class="p">(</span><span class="s1">'b'</span><span class="p">,</span> <span class="n">last</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
|
||
<span class="go">'bacde'</span>
|
||
</code></pre><div class="versionadded"><p><span class="yiyi-st" id="yiyi-314"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div></dd></dl></dd></dl><p><span class="yiyi-st" id="yiyi-315">除了通常的映射方法之外,有序字典还支持使用<a class="reference internal" href="functions.html#reversed" title="reversed"><code class="xref py py-func docutils literal"><span class="pre">reversed()</span></code></a>的反向迭代。</span></p><p><span class="yiyi-st" id="yiyi-316"><a class="reference internal" href="#collections.OrderedDict" title="collections.OrderedDict"><code class="xref py py-class docutils literal"><span class="pre">OrderedDict</span></code></a>对象之间的相等性测试是顺序敏感的,并且实现为<code class="docutils literal"><span class="pre">list(od1.items())==list(od2.items())</span></code>。</span><span class="yiyi-st" id="yiyi-317"><a class="reference internal" href="#collections.OrderedDict" title="collections.OrderedDict"><code class="xref py py-class docutils literal"><span class="pre">OrderedDict</span></code></a>对象与其他<a class="reference internal" href="collections.abc.html#collections.abc.Mapping" title="collections.abc.Mapping"><code class="xref py py-class docutils literal"><span class="pre">映射</span></code></a>对象之间的相等性测试与常规字典类似,对顺序不敏感。</span><span class="yiyi-st" id="yiyi-318">这允许在使用常规字典的任何位置替换<a class="reference internal" href="#collections.OrderedDict" title="collections.OrderedDict"><code class="xref py py-class docutils literal"><span class="pre">OrderedDict</span></code></a>对象。</span></p><p><span class="yiyi-st" id="yiyi-319"><a class="reference internal" href="#collections.OrderedDict" title="collections.OrderedDict"><code class="xref py py-class docutils literal"><span class="pre">OrderedDict</span></code></a>构造函数和<code class="xref py py-meth docutils literal"><span class="pre">update()</span></code>方法都接受关键字参数,但是它们的顺序丢失,因为Python的函数调用语义使用常规无序字典传递关键字参数。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-320"><span class="versionmodified">在版本3.5中更改:</span><a class="reference internal" href="#collections.OrderedDict" title="collections.OrderedDict"><code class="xref py py-class docutils literal"><span class="pre">OrderedDict</span></code></a>的项目、键和值<a class="reference internal" href="../glossary.html#term-dictionary-view"><span class="xref std std-term">视图</span></a>现在支持使用<a class="reference internal" href="functions.html#reversed" title="reversed"><code class="xref py py-func docutils literal"><span class="pre">reversed()</span></code></a>的反向迭代。</span></p></div><div class="section" id="ordereddict-examples-and-recipes"><h3><span class="yiyi-st" id="yiyi-321">8.3.6.1.</span><span class="yiyi-st" id="yiyi-322"><a class="reference internal" href="#collections.OrderedDict" title="collections.OrderedDict"><code class="xref py py-class docutils literal"><span class="pre">OrderedDict</span></code></a>示例和用法</span></h3><p><span class="yiyi-st" id="yiyi-323">由于有序字典会记住其插入顺序,因此可以与排序结合使用以创建排序字典:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="c1"># regular unsorted dictionary</span>
|
||
<span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'banana'</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="s1">'apple'</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="s1">'pear'</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">'orange'</span><span class="p">:</span> <span class="mi">2</span><span class="p">}</span>
|
||
|
||
<span class="gp">>>> </span><span class="c1"># dictionary sorted by key</span>
|
||
<span class="gp">>>> </span><span class="n">OrderedDict</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">items</span><span class="p">(),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">t</span><span class="p">:</span> <span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
|
||
<span class="go">OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])</span>
|
||
|
||
<span class="gp">>>> </span><span class="c1"># dictionary sorted by value</span>
|
||
<span class="gp">>>> </span><span class="n">OrderedDict</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">items</span><span class="p">(),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">t</span><span class="p">:</span> <span class="n">t</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span>
|
||
<span class="go">OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])</span>
|
||
|
||
<span class="gp">>>> </span><span class="c1"># dictionary sorted by length of the key string</span>
|
||
<span class="gp">>>> </span><span class="n">OrderedDict</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">items</span><span class="p">(),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">t</span><span class="p">:</span> <span class="nb">len</span><span class="p">(</span><span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">])))</span>
|
||
<span class="go">OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-324">当删除条目时,新的排序字典维护它们的排序顺序。</span><span class="yiyi-st" id="yiyi-325">但是,当添加新键时,键将附加到结尾,顺序不再保留。</span></p><p><span class="yiyi-st" id="yiyi-326">创建记住键<em>最后</em>插入顺序的有序字典变体也很简单。</span><span class="yiyi-st" id="yiyi-327">如果新条目覆盖现有条目,则原始插入位置将更改并移动到结尾:</span></p><pre><code class="language-python"><span></span><span class="k">class</span> <span class="nc">LastUpdatedOrderedDict</span><span class="p">(</span><span class="n">OrderedDict</span><span class="p">):</span>
|
||
<span class="s1">'Store items in the order the keys were last added'</span>
|
||
|
||
<span class="k">def</span> <span class="nf">__setitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
||
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span>
|
||
<span class="k">del</span> <span class="bp">self</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
||
<span class="n">OrderedDict</span><span class="o">.</span><span class="n">__setitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-328">有序字典可以与<a class="reference internal" href="#collections.Counter" title="collections.Counter"><code class="xref py py-class docutils literal"><span class="pre">Counter</span></code></a>类结合,以便计数器记住首次遇到的顺序元素:</span></p><pre><code class="language-python"><span></span><span class="k">class</span> <span class="nc">OrderedCounter</span><span class="p">(</span><span class="n">Counter</span><span class="p">,</span> <span class="n">OrderedDict</span><span class="p">):</span>
|
||
<span class="s1">'Counter that remembers the order elements are first encountered'</span>
|
||
|
||
<span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="s1">'</span><span class="si">%s</span><span class="s1">(</span><span class="si">%r</span><span class="s1">)'</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span> <span class="n">OrderedDict</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
|
||
|
||
<span class="k">def</span> <span class="nf">__reduce__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__class__</span><span class="p">,</span> <span class="p">(</span><span class="n">OrderedDict</span><span class="p">(</span><span class="bp">self</span><span class="p">),)</span>
|
||
</code></pre></div></div><div class="section" id="userdict-objects"><h2><span class="yiyi-st" id="yiyi-329">8.3.7.</span><span class="yiyi-st" id="yiyi-330"><a class="reference internal" href="#collections.UserDict" title="collections.UserDict"><code class="xref py py-class docutils literal"><span class="pre">UserDict</span></code></a>对象</span></h2><p><span class="yiyi-st" id="yiyi-331"><a class="reference internal" href="#collections.UserDict" title="collections.UserDict"><code class="xref py py-class docutils literal"><span class="pre">UserDict</span></code></a>是一个包裹了字典的对象。</span><span class="yiyi-st" id="yiyi-332">对这个类的需要已经部分地被直接从<a class="reference internal" href="stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal"><span class="pre">dict</span></code></a>子类化的能力所代替;但是,此类可以更容易使用,因为底层字典可作为属性访问。</span></p><dl class="class"><dt id="collections.UserDict"><span class="yiyi-st" id="yiyi-333"> <em class="property">class </em><code class="descclassname">collections.</code><code class="descname">UserDict</code><span class="sig-paren">(</span><span class="optional">[</span><em>initialdata</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-334">UserDict仿照字典。</span><span class="yiyi-st" id="yiyi-335">实例的内容保存在一个普通的字典当中,可以通过<a class="reference internal" href="#collections.UserDict" title="collections.UserDict"><code class="xref py py-class docutils literal"><span class="pre">UserDict</span></code></a>实例的属性<a class="reference internal" href="#collections.UserDict.data" title="collections.UserDict.data"><code class="xref py py-attr docutils literal"><span class="pre">data</span></code></a>访问。</span><span class="yiyi-st" id="yiyi-336">如果提供<em>initialdata</em>, <a class="reference internal" href="#collections.UserDict.data" title="collections.UserDict.data"><code class="xref py py-attr docutils literal"><span class="pre">data</span></code></a>就会被初始化为initialldata; note that a reference to <em>initialdata</em> will not be kept, allowing it be used for other purposes.</span></p><p><span class="yiyi-st" id="yiyi-337">除了支持一些方法和mappings的操作外,<a class="reference internal" href="#collections.UserDict" title="collections.UserDict"><code class="xref py py-class docutils literal"><span class="pre">UserDict</span></code></a>还提供以下属性:</span></p><dl class="attribute"><dt id="collections.UserDict.data"><span class="yiyi-st" id="yiyi-338"><code class="descname">data</code> </span></dt><dd><p><span class="yiyi-st" id="yiyi-339">data属性是存储<a class="reference internal" href="#collections.UserDict" title="collections.UserDict"><code class="xref py py-class docutils literal"><span class="pre">UserDict</span></code></a>类内容的真正字典。</span></p></dd></dl></dd></dl></div><div class="section" id="userlist-objects"><h2><span class="yiyi-st" id="yiyi-340">8.3.8.</span><span class="yiyi-st" id="yiyi-341"><a class="reference internal" href="#collections.UserList" title="collections.UserList"><code class="xref py py-class docutils literal"><span class="pre">UserList</span></code></a>对象</span></h2><p><span class="yiyi-st" id="yiyi-342">这个类充当列表对象的包装器。</span><span class="yiyi-st" id="yiyi-343">它是一个有用的基类,你自己的类列表类可以从它们继承,覆盖现有的方法或添加新的。</span><span class="yiyi-st" id="yiyi-344">这样,可以向列表中添加新的行为。</span></p><p><span class="yiyi-st" id="yiyi-345">这个类的需要已经部分地被直接从<a class="reference internal" href="stdtypes.html#list" title="list"><code class="xref py py-class docutils literal"><span class="pre">list</span></code></a>子类化的能力所取代;但是,此类可以更容易使用,因为底层列表可作为属性访问。</span></p><dl class="class"><dt id="collections.UserList"><span class="yiyi-st" id="yiyi-346"> <em class="property">class </em><code class="descclassname">collections.</code><code class="descname">UserList</code><span class="sig-paren">(</span><span class="optional">[</span><em>list</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-347">模拟列表的类。</span><span class="yiyi-st" id="yiyi-348">实例的内容保存在常规列表中,可以通过<a class="reference internal" href="#collections.UserList" title="collections.UserList"><code class="xref py py-class docutils literal"><span class="pre">UserList</span></code></a>实例的<a class="reference internal" href="#collections.UserList.data" title="collections.UserList.data"><code class="xref py py-attr docutils literal"><span class="pre">data</span></code></a>属性访问。</span><span class="yiyi-st" id="yiyi-349">实例的内容最初设置为<em>列表</em>的副本,默认为空列表<code class="docutils literal"><span class="pre">[]</span></code>。</span><span class="yiyi-st" id="yiyi-350"><em>列表</em>可以是任何可迭代的,例如真实的Python列表或<a class="reference internal" href="#collections.UserList" title="collections.UserList"><code class="xref py py-class docutils literal"><span class="pre">UserList</span></code></a>对象。</span></p><p><span class="yiyi-st" id="yiyi-351">除了支持可变序列的方法和操作,<a class="reference internal" href="#collections.UserList" title="collections.UserList"><code class="xref py py-class docutils literal"><span class="pre">UserList</span></code></a>实例提供以下属性:</span></p><dl class="attribute"><dt id="collections.UserList.data"><span class="yiyi-st" id="yiyi-352"><code class="descname">数据</code> </span></dt><dd><p><span class="yiyi-st" id="yiyi-353">用于存储<a class="reference internal" href="#collections.UserList" title="collections.UserList"><code class="xref py py-class docutils literal"><span class="pre">UserList</span></code></a>类的内容的实际<a class="reference internal" href="stdtypes.html#list" title="list"><code class="xref py py-class docutils literal"><span class="pre">list</span></code></a>对象。</span></p></dd></dl></dd></dl><p><span class="yiyi-st" id="yiyi-354"><strong>子类要求:</strong> <a class="reference internal" href="#collections.UserList" title="collections.UserList"><code class="xref py py-class docutils literal"><span class="pre">UserList</span></code></a>的子类应提供一个构造函数,可以使用无参数或一个参数进行调用。</span><span class="yiyi-st" id="yiyi-355">列表操作返回一个新序列,尝试创建实际实现类的实例。</span><span class="yiyi-st" id="yiyi-356">为此,假设可以使用单个参数调用构造函数,该参数是用作数据源的序列对象。</span></p><p><span class="yiyi-st" id="yiyi-357">如果派生类不希望遵守这个要求,这个类支持的所有特殊方法都需要被覆盖;请查阅来源,了解在这种情况下需要提供的方法的信息。</span></p></div><div class="section" id="userstring-objects"><h2><span class="yiyi-st" id="yiyi-358">8.3.9.</span><span class="yiyi-st" id="yiyi-359"><a class="reference internal" href="#collections.UserString" title="collections.UserString"><code class="xref py py-class docutils literal"><span class="pre">UserString</span></code></a>对象</span></h2><p><span class="yiyi-st" id="yiyi-360">类<a class="reference internal" href="#collections.UserString" title="collections.UserString"><code class="xref py py-class docutils literal"><span class="pre">UserString</span></code></a>充当字符串对象的包装器。</span><span class="yiyi-st" id="yiyi-361">这个类的需要已经部分地被从<a class="reference internal" href="stdtypes.html#str" title="str"><code class="xref py py-class docutils literal"><span class="pre">str</span></code></a>直接子类化的能力所取代;但是,此类可以更容易使用,因为底层字符串可作为属性访问。</span></p><dl class="class"><dt id="collections.UserString"><span class="yiyi-st" id="yiyi-362"> <em class="property">class </em><code class="descclassname">collections.</code><code class="descname">UserString</code><span class="sig-paren">(</span><span class="optional">[</span><em>sequence</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-363">模拟字符串或Unicode字符串对象的类。</span><span class="yiyi-st" id="yiyi-364">实例的内容保存在常规字符串对象中,可通过<a class="reference internal" href="#collections.UserString" title="collections.UserString"><code class="xref py py-class docutils literal"><span class="pre">UserString</span></code></a>实例的<code class="xref py py-attr docutils literal"><span class="pre">data</span></code>属性访问。</span><span class="yiyi-st" id="yiyi-365">实例的内容最初设置为<em>序列</em>的副本。</span><span class="yiyi-st" id="yiyi-366"><em>序列</em>可以是<a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a>,<a class="reference internal" href="stdtypes.html#str" title="str"><code class="xref py py-class docutils literal"><span class="pre">str</span></code></a>,<a class="reference internal" href="#collections.UserString" title="collections.UserString"><code class="xref py py-class docutils literal"><span class="pre">UserString</span></code></a>(或子类)可以使用内建<a class="reference internal" href="stdtypes.html#str" title="str"><code class="xref py py-func docutils literal"><span class="pre">str()</span></code></a>函数转换为字符串。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-367"><span class="versionmodified">在版本3.5中已更改:</span>新方法<code class="docutils literal"><span class="pre">__getnewargs__</span></code>,<code class="docutils literal"><span class="pre">__rmod__</span></code>,<code class="docutils literal"><span class="pre">casefold</span></code>,<code class="docutils literal"><span class="pre">format_map</span></code> <code class="docutils literal"><span class="pre">isprintable</span></code>和<code class="docutils literal"><span class="pre">maketrans</span></code>。</span></p></div></dd></dl></div></div></div> |