2017-08-17 10 views
-1

これがなぜ機能するのかを理解するのを助けてください。以下のコードは、反復可能なもののリストを示しています。しかし、またはオペレータの使用は、if..else文の中で他のように振る舞う。..ORとELSEはリスト内包表記で似ています

j = set() 
my_list = [1, 2, 3 ,3 , 3 ,4, 4] 
j_add = j.add 
twice = set(x for x in my_list if x in j or j_add(x)) 
print list(twice) 

行があることを期待する:

twice = set(x for x in my_list if x in j else j_add(x)) 

思想やブール値を返しません値

+1

技術的に言えば、あなたはリストの理解がなく、ジェネレータの表現があります。 –

+1

いいえ、 'または'は 'else'文ではありません。それはテストの一部です。 'if'や' while'文で同じブール式を使うことができます。 'または' ** short-circuits **の場合、左辺の式が真の値を生成した場合、右辺の式は実行されません。 –

+0

ありがとうございます。目的は重複を削除するのではなく、重複を取り除くことです。上記のコードは実行時に[3、4]を返します。 –

答えて

1

or演算子は、最後に評価された引数を返します。これはブール値であってもなくてもかまいません。

この動作はDocumentationで説明されています

andorは、彼らがFalseTrueに戻り値と型を制限していないのではなく、最後に評価された引数を返すどちらこと。 sが空の場合にデフォルト値に置き換える文字列の場合は、s or 'foo'という式で目的の値が得られます。

[T]彼は次の値がfalseとして解釈されます:すべてのFalseNone、数値ゼロもちろん

は、それは偽として解釈され、何が真と解釈されているものを覚えておくことができます空文字列とコンテナ(文字列、タプル、リスト、辞書、セット、フーチェンセットを含む)その他の値はすべてtrueと解釈されます。だから、式の中

:@MartijnPietersとして

A = B or C 

はコメントで指摘し、or表現短絡。最初の引数(この場合はB)がtrueと解釈された場合、式全体が真でなければならないため、2番目の引数(C)は決して評価されません。したがって、最初の引数(B)は "最後に評価された引数"であり、返されるものです。しかし、最初の引数(B)がfalseと解釈された場合、式の真実性を判定するために、第2引数(C)を評価する必要があります(短絡は発生しません)。その場合、「最後に評価された引数」は第2引数(C)であり、式が真か偽かにかかわらず返されます。

それが効果的にConditional Expressionと同じを達成

A = B if B else C 

ブール演算子の動作は最初から(または少なくとものために存在していながら、しかし、条件式のみが、バージョン2.5でのPythonに追加されましたとても長い間)。ほとんどの熟練したPythonプログラマーは、簡単に認識し、A = B or Cを使用する習慣があります。条件式は、単純なor(例えば、A = B if X else Cでは真理度がBではなく、Xに基づいています(単純な値から複雑な式になる可能性があります)の場合には、より複雑な条件のために予約されています。

しかし、JaredGoguenが彼の答えで指摘しているように、OPのサンプルでにorを変更すると実際にコードの動作が変わるため、注意する必要があります。このコードは、orオペレータのこの特定の動作に依存するように書かれています。条件式との代入には、orの使用を置き換えることはできません。追加のリファクタリングが必要な場合もあります。

1

ここで値を判断し、副作用をもたらすために短絡動作を使用しているので、これは良いコードではないと言います。or

与えられた条件を考えてみましょう:if x in j or j_add(x)

x in jorが短絡すると、条件付きの部分がスキップされ、Trueと評価されます。

x not in jとすると、j_add(x)というステートメントは真実性がチェックされます。このメソッドはNoneを返します。これは偽であるため、orFalseと評価されます。

したがって、条件全体がx in jと同じと評価されます。しかし、j_add(x)には、xjに追加するという副作用があります。この副作用はユニークなメンバーmy_listを素早く汚れた理解で記録するために悪用されています。

望むようelseからorはまだjを構築するだろう変更するが、それは不適切twiceに、Nonej_add(x)の戻り値を追加します。