<p>所以医生说:</p>
<blockquote>
<p>Formally, if a, b, c, ..., y, z are expressions and op1, op2, ..., opN are comparison operators, then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z, except that each expression is evaluated at most once.</p>
</blockquote>
<p>以及</p>
<blockquote>
<p>(but in both cases z is not evaluated at all when x < y is found to be false).</p>
</blockquote>
<p>对于标量</p>
<pre><code>In [20]: x=5
In [21]: 0<x<10
Out[21]: True
In [22]: 0<x and x<10
Out[22]: True
</code></pre>
<p>但是用一个数组</p>
^{pr2}$
<p>在需要标量布尔值的上下文中使用numpy布尔值时,会出现此值错误。在</p>
<pre><code>In [26]: (0<x)
Out[26]: array([ True, True, True], dtype=bool)
In [30]: np.array([True, False]) or True
...
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
In [33]: if np.array([True, False]): print('yes')
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
</code></pre>
<p>它计算<code>0<x</code>,但甚至不能计算<code>x<10</code>,因为它不能在<code>or/and</code>上下文中使用得到的布尔数组。<code>numpy</code>定义了<code>|</code>和{<cd6>},但没有<code>or</code>或{<cd8>}。在</p>
<pre><code>In [34]: (0<x) & x<10
Out[34]: array([ True, True, True], dtype=bool)
</code></pre>
<p>当我们使用<code>0 < x <10</code>时,我们隐含地期望计算标量链表达式的矢量化版本。在</p>
<pre><code>In [35]: f = np.vectorize(lambda x: 0<x<10, otypes=[bool])
In [36]: f(x)
Out[36]: array([ True, True, True], dtype=bool)
In [37]: f([-1,5,11])
Out[37]: array([False, True, False], dtype=bool)
</code></pre>
<p>请注意,尝试对列表应用链接甚至不会超过第一个<code><</code>:</p>
<pre><code>In [39]: 0 < [-1,5,11]
TypeError: unorderable types: int() < list()
</code></pre>
<hr/>
<p>这组表达式表示<code>&</code>运算符优先于<code><</code>运算符:</p>
<pre><code>In [44]: 0 < x & x<10
ValueError ...
In [45]: (0 < x) & x<10
Out[45]: array([ True, True, True], dtype=bool)
In [46]: 0 < x & (x<10)
Out[46]: array([False, True, False], dtype=bool)
In [47]: 0 < (x & x)<10
ValueError...
</code></pre>
<p>所以安全版本是<code>(0 < x) & (x<10)</code>,确保所有{<cd10>}在{<cd6>之前求值。在</p>