27

Python 構文に関する簡単な質問です。while ループの条件中に、関数から変数に値を代入したいと考えています。関数から返された値が false の場合、ループは中断されます。私はPHPでそれを行う方法を知っています。

while (($data = fgetcsv($fh, 1000, ",")) !== FALSE) 

ただし、Python で同様の構文を試すと、構文エラーが発生します。

4

4 に答える 4

38

2020年の答え:

Python 3.8以降、まさにあなたが望むことをする「セイウチ演算子」 :=が存在します:

while data := fgetcsv(fh, 1000, ",") != False:
    pass

(その fgetcsv 関数が存在する場合)

2013 年の回答: Python ではできません。式に代入はありません。少なくとも、= の代わりに == を誤って入力したり、その逆を行ったりすることはありません。

従来の Python スタイルは、 while True を使用してブレークするだけです。

while True:
    data = fgetcsv(fh, 1000, ",")
    if not data:
        break
    # Use data here

しかし、今日ではそれをジェネレーターに入れます:

def data_parts(fh):
    while True:
        data = fgetcsv(fh, 1000, ",")
        if not data:
            break
        yield data

ファイルを使用するコードでは、醜さが隠されているように:

for data in data_parts(fh):
    # Use data here

もちろん、実際に CSV の読み取りを行っている場合は、csv モジュールを使用してください。

于 2013-11-04T12:45:15.740 に答える
37

式では代入を使用できません。代入はそれ自体がステートメントであり、Python ステートメントを結合することはできません。

これは、言語設計者が明示的に選択したものです。2 つを使用して等価性をテスト=するつもりだった場合、誤って 1 つを使用して割り当てるのは非常に簡単です。==

割り当てをループに移動するか、ループのに割り当てて、ループ自体に新しい値を割り当てます。

特定の例では、Pythoncsvモジュールは高レベルの API を提供し、csv.reader()代わりに次のようにループします。

with open(csvfilename, 'rb') as csvfh:
    reader = csv.reader(csvfh)
    for row in reader:

ループ構成で割り当てる必要があることはめったにありません。通常、目前の問題を解決する (はるかに) 優れた方法があります。

そうは言っても、Python 3.8 の時点で、この言語には実際に:=代入演算子として使用される代入式があります。PEP 572を参照してください。代入式は、たとえば、作成中のリストにメソッドの戻り値を含める必要があり、その値をテストで使用できるようにする必要がある場合など、リスト内包表記で実際に役立ちます。

ここで、ジェネレーター式を使用する必要があります。

absolute = (os.path.abspath(p) for p in files)
filtered = [abs for abs in absolute if included(abs)]

ただし、割り当て式を使用すると、os.path.abspath()呼び出しをインライン化できます。

filtered = [abs for p in files if included(abs := os.path.abspath(p))]
于 2013-11-04T12:40:37.330 に答える
4

と呼ぶ小さな Python モジュールを作成しletました。これにより、関数が許可されている場所ならどこでも変数の割り当てを実行できます。

次のようにインストールします。

pip install let

以下があなたが探しているものを達成すると信じています:

from let import let

while let(data = fgetcsv(fh, 1000, ',')):
    # Do whatever you'd like with data here

しかし...ダンカンのコメントを使用するという元の質問iterは興味深いです。彼がそれを持ち出すまで、私はその機能に気づいていませんでした. それは議論の余地があります-センチネルを明示的に提供する必要がありますが、私の場合は気にせず、 y値が返されるのをiter待つだけです。fgetcsvFalse

于 2016-02-08T02:36:18.493 に答える