2

假设我有如下功能:

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在括号中标记了语法错误

4

3 回答 3

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()]
于 2012-12-07T23:36:42.537 回答
2

每当你发现自己有一个复杂的列表理解,试图弄清楚如何做一些复杂的事情却不知道如何做时,答案通常是把事情分解。表达式语法本质上比 Python 中的完整语句(或多语句套件)语法更受限制,以防止您编写以后无法阅读的内容。通常,这是一件好事——即使不是,你最好还是顺其自然,而不是试图与之抗争。

if在这种情况下,除了不知道如何将其写成表达式的子句之外,您的理解力很简单。所以,我会把条件变成一个单独的函数:

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

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

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

值得注意的是,在这种情况下——与一般情况一样——这并不能神奇地解决您的问题,它只是为您提供了更大的灵活性。例如,您可以使用FJ 建议的从后缀if到中缀的相同转换,但您也可以将其保留为,例如,像这样:orif

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

这实际上可能不是我写这个的方式,但你可以看到这是一种将你头脑中的东西转换为代码的简单方法,这在表达式中很难做到。

于 2012-12-07T23:57:17.257 回答
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的列表理解,并且作为循环的标准更具可读性..

于 2012-12-07T23:35:42.553 回答