如何扭转不平等陈述?

时间:2018-01-07 13:00:06

标签: python if-statement

如果将不等式乘以负数,则必须反转不等式的方向。

例如:

  • 1< x< 6(1)
  • -1> -x> -10(2)

如果x = 6,则与等式(1)和(2)一致。

有没有办法将不等式语句乘以Python的单行中的整数来反转符号?

从实际角度来看,我试图从TBLASTN结果中提取DNA /蛋白质序列。有股+1和-1,并且该条件语句之后的操作是相同的。

# one-liner statement I would like to implement
if (start_codon <= coord <= stop_codon)*strand:
    # do operation

# two-liner statement I know would work
if (start_codon <= coord <= stop_codon) and strand==1:
    # do operation
elif (start_codon >= coord >= stop_codon) and strand==-1:
    # do operation

4 个答案:

答案 0 :(得分:5)

您可以根据strand值选择下限和上限。这假定strand始终为1-1,并使用bool作为Python中的int子类,以便True和{ {1}}可用于索引成对:

False

答案 1 :(得分:4)

使用否定来反转操作

你写得像:

if (start_codon <= coord <= stop_codon) and strand==1:
    # do operation
elif (start_codon >= coord >= stop_codon) and strand==-1:
    # do operation

但这相当于:

if abs(strand) == 1 and strand * start_codon <= strand * coord <= strand * stop_codon:
    # do operation
    pass

或者我们可以假设abs(strand) == 1始终成立:

if strand * start_codon <= strand * coord <= strand * stop_codon:
    # do operation
    pass

理论证明

这是有效的,因为 x >= y-x <= -y 相等。因此,而不是&#34;倒转&#34;条件,我们将两个操作数乘以-1,因此隐式反转条件。让我们举个例子:

如果strand == 1,那么我们会评估-start_codon <= -coord <= -stop_codon。这相当于-start_codon <= -coord and -coord <= -stop_codon。现在我们可以使用start_codon >= coord and coord >= stop_codon来标准化两个子表达式,这相当于start_codon >= coord coord >= stop_codon。这意味着 -start_codon <= -coord <= -stop_codon相当于start_codon >= coord >= stop_codon

我们做出一个假设:那就是start_codonstop_codon数字(这样我们可以将它们相乘)。

经验证据

我们可以通过以下设置在经验上产生这种关系的经验证据:

import numpy as np

test_size = 1000
a = np.random.randn(test_size, 4)  # generate 1000x4 matrix of random data
a[:,3] = np.sign(a[:,3])  # make the last column -1 and 1
assert not (a[:,3] == 0).any()  # check no zeros in the last column
b = np.zeros(test_size)  # results for our relation
c = np.zeros(test_size)  # results for the question implementation

for i, (start_codon, coord, stop_codon, strand) in enumerate(a):
    b[i] = strand * start_codon <= strand * coord <= strand * stop_codon
    if (start_codon <= coord <= stop_codon) and strand==1:
        c[i] = 1
    elif (start_codon >= coord >= stop_codon) and strand==-1:
        c[i] = 1
    else:
        c[i] = 0

assert (b == c).all()

性能

如果我们采用上述代码,我们可以轻松修改它以检查性能如下:

import numpy as np
from operator import ge, le

test_size = 100000
a = np.random.randn(test_size, 4)  # generate 1000x4 matrix of random data
a[:,3] = np.sign(a[:,3])  # make the last column -1 and 1
assert not (a[:,3] == 0).any()  # check no zeros in the last column
b = np.zeros(test_size)  # target array

def code_kevin():
    for i, (start_codon, coord, stop_codon, strand) in enumerate(a):
        if (start_codon <= coord <= stop_codon) and strand==1:
            b[i] = 1
        elif (start_codon >= coord >= stop_codon) and strand==-1:
            b[i] = 1

def code_schwo():
    for i, (start_codon, coord, stop_codon, strand) in enumerate(a):
        cdns = (start_codon, stop_codon)
        if (cdns[strand==-1] <= coord <= cdns[strand==1]):
            b[i] = 1

def code_moinu():
    for i, (start_codon, coord, stop_codon, strand) in enumerate(a):
        codon_check = (le, ge)[strand==1]
        if codon_check(start_codon, coord) and codon_check(coord, stop_codon):
            b[i] = 1

def code_wille():
    for i, (start_codon, coord, stop_codon, strand) in enumerate(a):
        if strand * start_codon <= strand * coord <= strand * stop_codon:
            b[i] = 1

def code_fabio():
    for i, (start_codon, coord, stop_codon, strand) in enumerate(a):
        if pow(start_codon/coord, strand) <= 1 <= pow(stop_codon/coord, strand):
            b[i] = 1

作为操作,我们使用b[i] = 1。此外,我们总是使用if语句(而不是直接分配布尔值)来使比较时间更公平。

然后我们可以使用timeit.timeit,多次运行每个函数,并计算所需的秒数:

>>> timeit.timeit(code_kevin, number=100)
8.667507636011578
>>> timeit.timeit(code_schwo, number=100)
10.56048975896556
>>> timeit.timeit(code_wille, number=100)
8.908266504004132
>>> timeit.timeit(code_fabio, number=100)
13.454442486981861
>>> timeit.timeit(code_moinu, number=100)
10.350756354047917

答案 2 :(得分:1)

您可以使用简单的数学:

<TextBlock>
   <Run />
   <Run />
</TextBlock>

因为x ^ -1使比率事实上的反转反转了比较方向

答案 3 :(得分:1)

使用ge库中的leoperator的功能方法:

from operator import ge, le

# Sets `codon_check` function as:
#     - `ge`   if "strand == 1"
#     - `le`   otherwise 
codon_check = (le, ge)[strand==1]

if codon_check(start_codon, coord) and codon_check(coord, stop_codon):
    # do operation

下面: