8

いくつかの機会に、リスト内包表記またはジェネレーター式を短絡するための Python 構文が必要でした。

これは単純なリスト内包表記であり、Python での同等の for ループです。

my_list = [1, 2, 3, 'potato', 4, 5]
[x for x in my_list if x != 'potato']

result = []
for element in my_list:
    if element != 'potato':
        result.append(element)

この言語では、短絡する内包表記はサポートされていません。提案された構文、および Python の同等の for ループ:

[x for x in my_list while x != 'potato']
# --> [1, 2, 3]

result = []
for element in my_list:
    if element != 'potato':
        result.append(element)
    else:
        break

無限シーケンスを含む任意のイテラブルで動作し、ジェネレータ式の構文に拡張できる必要があります。私はlist(itertools.takewhile(lambda x: x != 'potato'), my_list)オプションとして認識していますが、

  • それは特にpythonicではありません-しばらく理解するほど読みやすくはありません
  • おそらくCPythonの理解ほど効率的でも高速でもありません
  • 出力を変換するには追加のステップが必要ですが、それは直接内包することができます。[x.lower() for x in mylist]
  • 原作者でさえあまり好きではないようです

私の質問は、なぜ文法をこのユースケースに拡張するのが良い考えではないのか、それともPython開発者がめったに役に立たないと考えているためにそれが不可能なのかについて、理論的なしわがありましたか? これは言語への単純な追加であり、便利な機能のように思えますが、隠れた機微や複雑さを見落としている可能性があります。

関連: これこれ

4

1 に答える 1

7

@Paul McGuire が指摘したように、それはPEP 3142で提案され、Guido によって拒否されたことが判明しました。

そのための PEP があることを知りませんでした。私はこれを拒否します。これ以上時間を無駄にする意味はありません。

しかし、彼は説明をしません。メーリングリストでは、それに対するいくつかのポイントは次のとおりです。

  • 「[理解は] 複数のネストされたステートメントと単一の式の間の慎重に設計された 1 対 1 の変換です。しかし、この提案はそれを無視し、破ります。(ここ)。」つまり、キーワードは明示的なループ内のwhilea に対応していません- そこにあるだけです。whilebreak
  • 「学ぶべきことがもう1つ増えるため、Pythonの学習が難しくなります。」(ここで引用)
  • ジェネレーター式とリスト内包表記の間に別の違いが追加されます。この構文をリスト内包表記に追加することも、まったく問題外のようです。

通常のリスト内包表記との基本的な違いの 1 つは、それwhileが宣言的ではなく、本質的に命令的であることです。それは、言語によって保証されていない実行順序に依存し、指示します(AFAIK)。これが、Python がアイデアを盗んだ Haskell の理解に含まれていない理由だと思います。

もちろん、ジェネレーター式には方向がありますが、それらの要素は事前に計算されている場合があります-再び、AFAIK。言及されたPEPは、ジェネレーター式に対してのみそれを提案しました-これはある程度理にかなっています。

もちろん、Pythonとにかく命令型言語ですが、問題が発生します。

順序付けされていないコレクションから選択するのはどうですか?

[x for x in {1,2,3} while x!=2]

単純なループにもありませんが、それforは言語によって強制できないものです。takewhileはこの質問に答えますが、それは恣意的な答えです。


最後のポイントとして、一貫性のために のサポートが必要になることに注意してくださいdropwhile。何かのようなもの

[x for x in my_list from x != 'potato']

これは、同等のfor構造とはさらに関係がなく、今回my_listは単に iterable である場合、ショート サーキットではない可能性があります。

于 2013-06-05T04:21:47.680 に答える