mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 06:55:36 +08:00
52 lines
17 KiB
HTML
52 lines
17 KiB
HTML
<div class="body" role="main"><div class="section" id="module-bisect"><h1><span class="yiyi-st" id="yiyi-10">8.6. <a class="reference internal" href="#module-bisect" title="bisect: Array bisection algorithms for binary searching."><code class="xref py py-mod docutils literal"><span class="pre">bisect</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/bisect.py">Lib / bisect.py</a></span></p><p><span class="yiyi-st" id="yiyi-12">此模块支持以排序顺序维护列表,而不必在每次插入后对列表进行排序。</span><span class="yiyi-st" id="yiyi-13">对于具有昂贵的比较操作的项目的长列表,这可以是对更常见的方法的改进。</span><span class="yiyi-st" id="yiyi-14">该模块称为<a class="reference internal" href="#module-bisect" title="bisect: Array bisection algorithms for binary searching."><code class="xref py py-mod docutils literal"><span class="pre">bisect</span></code></a>,因为它使用基本对分算法来完成其工作。</span><span class="yiyi-st" id="yiyi-15">源代码作为算法的工作示例可能是最有用的(边界条件已经是对的!</span><span class="yiyi-st" id="yiyi-16">)。</span></p><p><span class="yiyi-st" id="yiyi-17">提供以下功能:</span></p><dl class="function"><dt id="bisect.bisect_left"><span class="yiyi-st" id="yiyi-18"><code class="descclassname">bisect.</code><code class="descname">bisect_left</code><span class="sig-paren">(</span><em>a</em>, <em>x</em>, <em>lo=0</em>, <em>hi=len(a)</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-19">在<em>a</em>中找到<em>x</em>的插入点以保持排序顺序。</span><span class="yiyi-st" id="yiyi-20">参数<em>lo</em>和<em>hi</em>可以用于指定应该考虑的列表的子集;默认情况下使用整个列表。</span><span class="yiyi-st" id="yiyi-21">如果<em>x</em>已存在于<em>a</em>中,则插入点将在任何现有条目之前(左侧)。</span><span class="yiyi-st" id="yiyi-22">返回值适合用作<code class="docutils literal"><span class="pre">list.insert()</span></code>的第一个参数,假设<em>a</em>已经排序。</span></p><p><span class="yiyi-st" id="yiyi-23">返回的插入点<em>i</em>将数组<em>a</em>分成两半,使得<code class="docutils literal"><span class="pre">all(val</span> <span class="pre"> <span class="pre">x</span> <span class="pre">for</span> <span class="pre">val</span> <span class="pre">in</span> <span class="pre">a [lo:i])</span> 对于<span class="pre"><code class="docutils literal"><span class="pre">all(val</span> <span class="pre">> =</span> <span class="pre">x</span> <span class="pre">t15> <span class="pre">in</span> <span class="pre">a [i:hi])</span></span></code>。</span></span></code></span></p></dd></dl><dl class="function"><dt id="bisect.bisect_right"><span class="yiyi-st" id="yiyi-24"><code class="descclassname">bisect.</code><code class="descname">bisect_right</code><span class="sig-paren">(</span><em>a</em>, <em>x</em>, <em>lo=0</em>, <em>hi=len(a)</em><span class="sig-paren">)</span></span></dt><dt id="bisect.bisect"><span class="yiyi-st" id="yiyi-25"> <code class="descclassname">bisect.</code><code class="descname">bisect</code><span class="sig-paren">(</span><em>a</em>, <em>x</em>, <em>lo=0</em>, <em>hi=len(a)</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-26">类似于<a class="reference internal" href="#bisect.bisect_left" title="bisect.bisect_left"><code class="xref py py-func docutils literal"><span class="pre">bisect_left()</span></code></a>,但返回在<em>a</em>中<em>x</em>的任何现有条目之后(右侧)的插入点。</span></p><p><span class="yiyi-st" id="yiyi-27">The returned insertion point <em>i</em> partitions the array <em>a</em> into two halves so that <code class="docutils literal"><span class="pre">all(val</span> <span class="pre"><=</span> <span class="pre">x</span> <span class="pre">for</span> <span class="pre">val</span> <span class="pre">in</span> <span class="pre">a[lo:i])</span></code> for the left side and <code class="docutils literal"><span class="pre">all(val</span> <span class="pre">></span> <span class="pre">x</span> <span class="pre">for</span> <span class="pre">val</span> <span class="pre">in</span> <span class="pre">a[i:hi])</span></code> for the right side.</span></p></dd></dl><dl class="function"><dt id="bisect.insort_left"><span class="yiyi-st" id="yiyi-28"><code class="descclassname">bisect.</code><code class="descname">insort_left</code><span class="sig-paren">(</span><em>a</em>, <em>x</em>, <em>lo=0</em>, <em>hi=len(a)</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-29">以排序顺序在<em>a</em>中插入<em>x</em>。</span><span class="yiyi-st" id="yiyi-30">这相当于<code class="docutils literal"><span class="pre">a.insert(bisect.bisect_left(a,</span> <span class="pre">x,</span> <span class="pre">lo,</span> <span class="pre">hi) t4> <span class="pre">x)</span></span></code>,假设<em>a</em>已经排序。</span><span class="yiyi-st" id="yiyi-31">请记住,O(log n)搜索由缓慢的O(n)插入步骤控制。</span></p></dd></dl><dl class="function"><dt id="bisect.insort_right"><span class="yiyi-st" id="yiyi-32"><code class="descclassname">bisect.</code><code class="descname">insort_right</code><span class="sig-paren">(</span><em>a</em>, <em>x</em>, <em>lo=0</em>, <em>hi=len(a)</em><span class="sig-paren">)</span></span></dt><dt id="bisect.insort"><span class="yiyi-st" id="yiyi-33"><code class="descclassname">bisect.</code><code class="descname">insort</code><span class="sig-paren">(</span><em>a</em>, <em>x</em>, <em>lo=0</em>, <em>hi=len(a)</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-34">类似于<a class="reference internal" href="#bisect.insort_left" title="bisect.insort_left"><code class="xref py py-func docutils literal"><span class="pre">insort_left()</span></code></a>,但在<em>x</em>的任何现有条目后在<em>a</em>中插入<em>x</em>。</span></p></dd></dl><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-35">也可以看看</span></p><p class="last"><span class="yiyi-st" id="yiyi-36"><a class="reference external" href="https://code.activestate.com/recipes/577197-sortedcollection/">SortedCollection食谱</a>使用bisect通过直接搜索方法构建一个全功能的容器类,并支持键功能。</span><span class="yiyi-st" id="yiyi-37">密钥预先计算以在搜索期间节省对密钥功能的不必要的调用。</span></p></div><div class="section" id="searching-sorted-lists"><h2><span class="yiyi-st" id="yiyi-38">8.6.1.</span><span class="yiyi-st" id="yiyi-39">搜索排序列表</span></h2><p><span class="yiyi-st" id="yiyi-40">The above <a class="reference internal" href="#module-bisect" title="bisect: Array bisection algorithms for binary searching."><code class="xref py py-func docutils literal"><span class="pre">bisect()</span></code></a> functions are useful for finding insertion points but can be tricky or awkward to use for common searching tasks.</span><span class="yiyi-st" id="yiyi-41">以下五个函数显示如何将它们转换为排序列表的标准查找:</span></p><pre><code class="language-python"><span></span><span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
|
||
<span class="s1">'Locate the leftmost value exactly equal to x'</span>
|
||
<span class="n">i</span> <span class="o">=</span> <span class="n">bisect_left</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">i</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="ow">and</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="n">x</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="n">i</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span>
|
||
|
||
<span class="k">def</span> <span class="nf">find_lt</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
|
||
<span class="s1">'Find rightmost value less than x'</span>
|
||
<span class="n">i</span> <span class="o">=</span> <span class="n">bisect_left</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">i</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span>
|
||
|
||
<span class="k">def</span> <span class="nf">find_le</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
|
||
<span class="s1">'Find rightmost value less than or equal to x'</span>
|
||
<span class="n">i</span> <span class="o">=</span> <span class="n">bisect_right</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">i</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span>
|
||
|
||
<span class="k">def</span> <span class="nf">find_gt</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
|
||
<span class="s1">'Find leftmost value greater than x'</span>
|
||
<span class="n">i</span> <span class="o">=</span> <span class="n">bisect_right</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">i</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span>
|
||
|
||
<span class="k">def</span> <span class="nf">find_ge</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
|
||
<span class="s1">'Find leftmost item greater than or equal to x'</span>
|
||
<span class="n">i</span> <span class="o">=</span> <span class="n">bisect_left</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">i</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span>
|
||
</code></pre></div><div class="section" id="other-examples"><h2><span class="yiyi-st" id="yiyi-42">8.6.2.</span><span class="yiyi-st" id="yiyi-43">其他示例</span></h2><p id="bisect-example"><span class="yiyi-st" id="yiyi-44"><a class="reference internal" href="#module-bisect" title="bisect: Array bisection algorithms for binary searching."><code class="xref py py-func docutils literal"><span class="pre">bisect()</span></code></a>函数可用于数值表查找。</span><span class="yiyi-st" id="yiyi-45">本示例使用<a class="reference internal" href="#module-bisect" title="bisect: Array bisection algorithms for binary searching."><code class="xref py py-func docutils literal"><span class="pre">bisect()</span></code></a>根据一组有序数字断点查找考试成绩的字母分数:90,向上为“A”,80至89为“ B',等等:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="k">def</span> <span class="nf">grade</span><span class="p">(</span><span class="n">score</span><span class="p">,</span> <span class="n">breakpoints</span><span class="o">=</span><span class="p">[</span><span class="mi">60</span><span class="p">,</span> <span class="mi">70</span><span class="p">,</span> <span class="mi">80</span><span class="p">,</span> <span class="mi">90</span><span class="p">],</span> <span class="n">grades</span><span class="o">=</span><span class="s1">'FDCBA'</span><span class="p">):</span>
|
||
<span class="gp">... </span> <span class="n">i</span> <span class="o">=</span> <span class="n">bisect</span><span class="p">(</span><span class="n">breakpoints</span><span class="p">,</span> <span class="n">score</span><span class="p">)</span>
|
||
<span class="gp">... </span> <span class="k">return</span> <span class="n">grades</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
|
||
<span class="gp">...</span>
|
||
<span class="gp">>>> </span><span class="p">[</span><span class="n">grade</span><span class="p">(</span><span class="n">score</span><span class="p">)</span> <span class="k">for</span> <span class="n">score</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">33</span><span class="p">,</span> <span class="mi">99</span><span class="p">,</span> <span class="mi">77</span><span class="p">,</span> <span class="mi">70</span><span class="p">,</span> <span class="mi">89</span><span class="p">,</span> <span class="mi">90</span><span class="p">,</span> <span class="mi">100</span><span class="p">]]</span>
|
||
<span class="go">['F', 'A', 'C', 'C', 'B', 'A', 'A']</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-46">与<a class="reference internal" href="functions.html#sorted" title="sorted"><code class="xref py py-func docutils literal"><span class="pre">sorted()</span></code></a>函数不同的是,<a class="reference internal" href="#module-bisect" title="bisect: Array bisection algorithms for binary searching."><code class="xref py py-func docutils literal"><span class="pre">bisect()</span></code></a>函数具有<em>键</em>或<em>颠倒 t7 >因为这会导致设计效率低下(连续调用平分函数不会“记住”以前的所有键查找)。</em></span></p><p><span class="yiyi-st" id="yiyi-47">相反,最好搜索预先计算的密钥列表以查找有问题的记录的索引:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">data</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">'red'</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span> <span class="p">(</span><span class="s1">'blue'</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="s1">'yellow'</span><span class="p">,</span> <span class="mi">8</span><span class="p">),</span> <span class="p">(</span><span class="s1">'black'</span><span class="p">,</span> <span class="mi">0</span><span class="p">)]</span>
|
||
<span class="gp">>>> </span><span class="n">data</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">r</span><span class="p">:</span> <span class="n">r</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
|
||
<span class="gp">>>> </span><span class="n">keys</span> <span class="o">=</span> <span class="p">[</span><span class="n">r</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">data</span><span class="p">]</span> <span class="c1"># precomputed list of keys</span>
|
||
<span class="gp">>>> </span><span class="n">data</span><span class="p">[</span><span class="n">bisect_left</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="mi">0</span><span class="p">)]</span>
|
||
<span class="go">('black', 0)</span>
|
||
<span class="gp">>>> </span><span class="n">data</span><span class="p">[</span><span class="n">bisect_left</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="mi">1</span><span class="p">)]</span>
|
||
<span class="go">('blue', 1)</span>
|
||
<span class="gp">>>> </span><span class="n">data</span><span class="p">[</span><span class="n">bisect_left</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="mi">5</span><span class="p">)]</span>
|
||
<span class="go">('red', 5)</span>
|
||
<span class="gp">>>> </span><span class="n">data</span><span class="p">[</span><span class="n">bisect_left</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="mi">8</span><span class="p">)]</span>
|
||
<span class="go">('yellow', 8)</span>
|
||
</code></pre></div></div></div> |