2012-12-07 38 views
2

假设我有一个功能类似如下:嵌入式if语句

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。我试过(如上图所示),通过包括两项合计为括号但蟒蛇标志在括号中的语法错误

+3

只是一个评论,这是一个列表理解的复杂并不是非常pythonic。为什么不把它写成标准的'for'和'list.append()'?另外,如果语句 –

+1

parens是有效的并且经常用于分组东西...,则括号在python中无效......但是不是必需的...(至少在py2中) –

+1

@BrianCray:从技术上讲,本例中没有if语句,只是列表理解中的if子句,它具有类似但不同的语法。 – abarnert

回答

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

只是更改顺序

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 

的评论中提到,这不是一个很Python的列表理解并且作为循环的标准将更具可读性。

2

无论何时你发现自己有一个复杂的列表解析,试图找出如何做复杂的,而不是知道如何,答案通常是分手。表达式语法本质上比Python中的完整语句(或多语句套件)语法更有限,以防止您编写以后无法阅读的内容。通常情况下,这是一件好事 - 即使不这样做,最好还是继续努力,而不是试图与之抗争。

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

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

这让你使用完整的多语句语法的条件。它还可以让你给这个条件一个名字(希望比isMyKindOfKey更好);使得闭包捕获的参数,局部值更加明确;让您单独测试该功能或重新使用它;等等。

在循环本身是非平凡部分(或者只有很多嵌套)的情况下,将整个理解分解为明确的for循环和append通常会更有意义,但是我不'我认为这是必要的。

值得注意的是,在这种情况下 - 正如一般情况 - 这不会奇迹般地解决您的问题,它只是为您提供更大的灵活性。例如,你可以使用同样的转变,从后缀if到中缀or是FJ建议,但你也可以把它作为一个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 

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