嵌入if语句

时间:2012-12-07 23:32:14

标签: python if-statement

假设我有以下功能:

bigrams=[(k,v) for (k,v) in dict_bigrams.items()
         if k[:pos_qu]==selection[:pos_qu]
         and (k[pos_qu+1:]==selection[pos_qu+1:] if pos_qu!=1)
         and k[pos_qu] not in alphabet.values()]

我想创建第二个条件,即k[pos_qu+1:]==selection[pos_qu+1:]依赖于另一个if语句if pos_qu!=1。我试过(如上所示)将两者一起括在括号中但python在括号中标记语法错误

3 个答案:

答案 0 :(得分:2)

如果我正确理解您的要求,您只需要检查k[pos_qu+1:]==selection[pos_qu+1:]是否也符合条件pos_qu!=1。您可以将其重新表述为以下条件:

pos_qu==1 or k[pos_qu+1:]==selection[pos_qu+1:]

理解这一点:

bigrams=[(k,v) for (k,v) in dict_bigrams.items()
         if k[:pos_qu]==selection[:pos_qu]
         and (pos_qu==1 or k[pos_qu+1:]==selection[pos_qu+1:])
         and k[pos_qu] not in alphabet.values()]

答案 1 :(得分:2)

每当你发现自己有一个复杂的列表理解,试图弄清楚如何做一些复杂的事情而不知道如何做,答案往往就是打破局面。表达式语法本质上比Python中的完整语句(或多语句套件)语法更有限,以防止您编写以后无法阅读的内容。通常情况下,这是一件好事 - 即使不是这样,你最好还是选择与之抗争。

在这种情况下,你有一个简单的理解,除了if子句,你不知道如何写作表达式。所以,我将条件转变为一个单独的函数:

def isMyKindOfKey(k):
    … condition here
[(k,v) for (k,v) in dict_bigrams.items() if isMyKindOfKey(k)]

这使您可以对条件使用完整的多语句语法。它还允许您为条件命名(希望比isMyKindOfKey更好);使闭包捕获的参数,局部值更明确;让你单独测试或重用它;等

如果循环本身是非平凡的部分(或者只有很多嵌套),通常将整个理解分解为显式的for循环和附加更有意义,但我不认为这是必要的。

值得注意的是,在这种情况下 - 一般情况下 - 这并不会神奇地解决您的问题,它只是为您提供了更大的灵活性。例如,您可以使用F.J建议的从postfix if到infix or的相同转换,但您也可以将其保留为if,例如,如下所示:

def isMyKindOfKey(k):
    retval = k[:pos_qu]==selection[:pos_qu]
    if pos_qu!=1:
        retval = retval and (k[pos_qu+1:]==selection[pos_qu+1:])
    retval = retval and (k[pos_qu] not in alphabet.values())
    return retval

这实际上可能不是我写这个的方式,但你可以看到这是如何将你头脑中的内容转换成代码的一种微不足道的方式,这在表达式中很难做到。

答案 2 :(得分:1)

只需更改订单

bigrams=[(k,v) for (k,v) in dict_bigrams.items()
     if k[:pos_qu]==selection[:pos_qu] #evaluated first
     and  pos_qu!=1 #if true continue and evaluate this next
     and (k[pos_qu+1:]==selection[pos_qu+1:]) #if pos_qu != 1 lastly eval this

正如评论所提到的那样,这不是一个非常pythonic列表理解,并且作为循环的标准会更具可读性。