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:]2 番目の条件、つまり別の if ステートメントに依存する条件を作成したいと思いif pos_qu!=1ます。私は(上記のように)2つを一緒に括弧に入れて試しましたが、Pythonは括弧で構文エラーにフラグを立てます

4

3 に答える 3

2

複雑なリスト内包表記に陥ったり、複雑なことを行う方法を理解しようとしたり、方法がわからない場合はいつでも、答えは通常、物事を分割することです。式の構文は、Python の完全なステートメント (または複数ステートメント スイート) の構文よりも本質的に制限されているため、後で読むことができないものを作成することはできません。通常、それは良いことですが、そうでない場合でも、それと戦おうとするよりも、それに沿った方がよいでしょう.

この場合、if式としての書き方がわからない句を除いて、自明な理解が得られます。したがって、条件を別の関数に変換します。

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

これにより、条件に完全なマルチステートメント構文を使用できます。また、条件に名前を付けることもできます (できれば よりも優れた名前を付けることができますisMyKindOfKey)。パラメータ、クロージャーによってキャプチャされたローカル値などをより明示的にします。関数を個別にテストしたり、再利用したりできます。等

ループ自体が重要な部分である (または入れ子がたくさんある) 場合は、通常、理解全体を明示的な for ループに分割して追加する方が理にかなっていますが、ここでは必要ないと思います。

この場合、一般にそうであるように、これで問題が魔法のように解決されるわけではなく、より柔軟に解決できることに注意してください。たとえば、 FJ が提案する後置からif中置への同じ変換を使用できますが、次の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

これは実際には私が書く方法ではないかもしれませんが、これが、頭の中にあるものをコードに変換する簡単な方法であることがわかります。これを式で行うのは非常に困難です。

于 2012-12-07T23:57:17.257 に答える
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 に答える
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なリスト内包表記ではなく、標準のforループとしてはるかに読みやすいでしょう..

于 2012-12-07T23:35:42.553 に答える