49

andそしてor、彼らが評価した最後の要素を返しますが、なぜPythonの組み込み関数がないのanyですか?

このように自分で実装するのはとても簡単だということですが、それでもなぜだろうと思っています。

def any(l):
    for x in l:
        if x:
            return x
    return x

編集:

以下の回答に追加するために、この問題に関するあなたがたの強力な皇帝の同じメーリングリストからの実際の引用があります:

常にTrueとFalseを返すのか、それとも最初のフェール/パス要素を返すのか。私もブログを書く前にそれで遊んで、エンドケース(シーケンスが空の場合、またはすべての要素がテストに失敗した場合)を満足のいくものにすることはできないことに気付きました:引数がブール値の反復可能である場合、Noneを選択すると奇妙に感じます。引数が非ブールオブジェクトの反復可能である場合、Falseを選択すると奇妙に感じます。

Guido van Rossum(ホームページ:http ://www.python.org/~guido/ )

4

7 に答える 7

48

この問題は、GuidoVanRossumがPython2.5への追加anyを提案した2005年にPython開発者のメーリングリストで取り上げられましたall

Bill Janssenは、次のように実装するように要求しました

def any(S):
    for x in S:
        if x:
            return x
    return S[-1]

def all(S):
    for x in S:
        if not x:
            return x
    return S[-1]

anyとを実装したレイモンド・ヘッティンガーは、allその理由anyに具体的に対処し、次のようにall行動しないでください:andor

時間が経つにつれて、私はこれらや他のitertoolsレシピについてのフィードバックを得てきました。これらのレシピまたはGuidoのバージョンのTrue/Falseの戻り値に異議を唱える人は誰もいません。

Guidoのバージョンは、いずれか/すべてが述語であるという通常の期待に一致します。また、Python独自の「and」と「or」の実装で現在人々が経験しているようなエラー/混乱を回避します。

最後の要素を返すことは悪ではありません。それはただ奇妙で、予想外で、そして自明ではありません。これでトリッキーになりたいという衝動に抵抗してください。

メーリングリストは大部分が同意し、今日のように実装を残しました。

于 2012-04-16T19:56:51.577 に答える
22

andまた、常にオペランドの1つを返すorように適切に定義できます。ただし、入力シーケンスから値を返すように常に適切に定義することはできません。具体的には、リストが空の場合はそうすることができません。と現在の両方で、この状況で明確に定義された結果が得られます。Falseを返し、Trueを返します。ブール値を返すことを余儀なくされることもあればシーケンスからアイテムを返すこともあります。これにより、不快で驚くべきインターフェイスが作成されます。シンプルで一貫している方がはるかに良いです。anyallanyallanyall

于 2012-04-16T19:41:07.227 に答える
11

を開始し、代入式(PEP 572)(演算子)をPython 3.8導入すると、代わりに、式の証人または式の反例を明示的にキャプチャできます。:=anyall


PEPの説明からいくつかの例を引用するには:

if any(len(long_line := line) >= 100 for line in lines):
  print("Extremely long line:", long_line)
if all((nonblank := line).strip() == '' for line in lines):
  print("All lines are blank")
else:
  print("First non-blank line:", nonblank)
于 2019-04-28T10:18:22.853 に答える
5

私はpython-ideasでこれと同じ質問をしましたが、その理由は、シーケンスが空のときに値を返す必要があり、それらの値はとでなければならないと言わany()れました。これは私には弱い議論のようです。 all()FalseTrue

関数は今は変更できませんが、最初に遭遇したtrue-ishまたはfalse-ishの値を返す場合、それらはより便利であり、それらが一般化する演算子andと演算子のより良い類似物になると思います。or

于 2012-04-16T19:37:48.790 に答える
3

の動作andorは、歴史的な理由で存在します。

Pythonが三項演算/条件式を使用する前は、条件に値を使用する場合はを使用していましたandorこのような式は、条件式の構文で書き直すことができます。

true_val if condition else false_val

基本的に、これらは2つの関数でオーバーロードされており、互換性の理由から、変更されていません。

それは他の操作を過負荷にする理由ではありません。ブール値である任意のアイテムに対して条件が真であるかどうかanyを通知する必要があるように思われるため、を返す必要があります。bool

于 2012-04-16T19:40:07.700 に答える
0

Anyブール値を返します。これは、引数のいずれかが真であるかどうかを検討する前に、その引数をブール値のリストとして効果的に処理するためです。評価した要素を返していますが、これはたまたまブール値です。

自分のバージョンのをいつ使用しますanyか?それがboolsのリストにある場合、あなたはすでに正しい答えを持っています。それ以外の場合は、防御しているだけでNone、次のように表現される可能性があります。

filter(lambda x: x != None, l)[0]

また:

[x for x in l if x != None][0]

これは、より明確な意図の表明です。

于 2012-04-16T19:31:17.437 に答える
0

anyの値がFalseまたは入力の値の1つである可能性があることはすぐにはわかりません。また、ほとんどの用途は次のようになります

tmp = any(iterable)
if tmp:
   tmp.doSomething()
else:
   raise ValueError('Did not find anything')

それはあなたが飛躍する前に見て、したがって非Pythonです。比較対象:

next(i for i in iterable if i).doSomething()
# raises StopIteration if no value is true

andおよびの動作はor、当時使用できなかった条件式のドロップインとして歴史的に有用でした。

于 2012-04-16T19:34:36.617 に答える