25

Python で無限ループを作成する 2 つの方法を見てきました。

  1. while 1:
        do_something()
    
  2. while True:
        do_something()
    

これらの間に違いはありますか?一方は他方よりもPythonicですか?

4

11 に答える 11

47

基本的には問題ではありません。そのような細目は、何かが「pythonic」であるかどうかに実際には影響しません。

ただし、トリビアに興味がある場合は、いくつかの違いがあります。

  1. 組み込みのブール型は Python 2.3 まで存在しなかったため、古いバージョンで実行することを意図したコードはこの形式を使用する傾向がありますwhile 1:。たとえば、標準ライブラリに表示されます。

  2. True および False ビルトインは、Python 3 より前では予約語ではないため、値を変更して割り当てることができました。True = 1コードは下位互換性を維持できるため、これは上記のケースに役立ちますが、名前Trueを使用するたびにグローバル ディクショナリで名前を検索する必要があることを意味します。

  3. 上記の制限により、Python 2 では使用できない定数整数の最適化があるため、2 つのバージョンがコンパイルされるバイトコードは異なりますTrue。Python は をコンパイルするときに1常に非ゼロであることを認識できるため、条件付きジャンプを削除し、定数をまったくロードしません。

    >>> import dis
    >>> def while_1():
    ...     while 1:
    ...         pass
    ...
    >>> def while_true():
    ...     while True:
    ...         pass
    ...
    >>> dis.dis(while_1)
      2           0 SETUP_LOOP               5 (to 8)
    
      3     >>    3 JUMP_ABSOLUTE            3
                  6 POP_TOP
                  7 POP_BLOCK
            >>    8 LOAD_CONST               0 (None)
                 11 RETURN_VALUE
    >>> dis.dis(while_true)
      2           0 SETUP_LOOP              12 (to 15)
            >>    3 LOAD_GLOBAL              0 (True)
                  6 JUMP_IF_FALSE            4 (to 13)
                  9 POP_TOP
    
      3          10 JUMP_ABSOLUTE            3
            >>   13 POP_TOP
                 14 POP_BLOCK
            >>   15 LOAD_CONST               0 (None)
                 18 RETURN_VALUE
    

そのためwhile True:、少し読みやすく、while 1:古いバージョンの Python に少し優しくなっています。最近では Python 2.2 で実行する必要がなくなったり、ループのバイトコード数を気にする必要がなくなったりするため、前者の方がわずかに適しています。

于 2010-02-14T18:08:33.043 に答える
11

最も Pythonic な方法は、常に最も読みやすいものになります。使用するwhile True:

于 2010-02-14T17:47:32.923 に答える
5

それは本当に問題ではありません。どちらも読みにくく理解しにくいわけではありませんが、個人的には常に を使用しますwhile Trueが、これはもう少し明示的です。

より一般的に言えば、人々が Python で書いた非常に多くの while-break ループは、別のものである可能性があります。時々、人々が を書いているのを見かけますがi = 0; while True: i += 1 ...、これは に置き換えることができ、これを書くことができるときにfor i in itertools.count()書いている人もいます。これは、学習が必要ですが、ボイラープレートが少なく、ばかげた間違いをする機会が少なくなります。while True: foo = fun() if foo is None: breakfor foo in iter(fun, None)

于 2010-02-14T18:22:55.773 に答える
4

ない。

どちらも、コードをスキャンして を探す必要があることを意味しbreak、停止条件が属する場所を確認することができません。

私は可能な限りこの種のことを回避しようとします。それが不可能な場合は、コードが次のように語るようにします。

while not found_answer:
    check_number += 1
    if check_number == 42:
        found_answer = True

編集:上記の「回避」という言葉は十分に明確ではなかったようです. 基本的に無限ループを使用し、ループ内のどこかから離れる ( を使用するbreak)ことは、通常、完全に避ける必要があります。時々それは不可能です。その場合、私は上記のコードのようなものを使用するのが好きですが、それでも同じ概念を表しています.上記の コードは妥協にすぎません.関数を呼び出さないのと同じようにdo_something_with_args(*args)

于 2010-02-14T17:57:32.743 に答える
3

IMO の 2 番目のオプションはより明白です。

を取り除き、よりコンパクトなコードを書くことができればwhile、それはより Pythonic になるかもしれません。
例えば:

# Get the even numbers in the range 1..10
# Version 1
l = []
n = 1
while 1:
    if n % 2 == 0: l.append(n)
    n += 1
    if n > 10: break
print l

# Version 2
print [i for i in range(1, 11) if i % 2 == 0]

# Version 3
print range(2, 11, 2)
于 2010-02-14T17:45:46.083 に答える
2

これは主にスタイルの問題だと思います。どちらも無限ループとして簡単に理解できるはずです。

ただし、個人的には2番目のオプションを好みます。これは、特にCのバックグラウンドを持たないプログラマーにとっては、理解するのに精神的なマイクロステップが少なくて済むためです。

于 2010-02-14T17:36:13.873 に答える
2

True最初のものは、まだ定義されていない初期バージョンでも機能します。

于 2010-02-14T17:37:34.730 に答える
2

有限時間で終了すると思われるアルゴリズムがある場合は、これをお勧めします。これは常により安全ですwhile True

maxiter = 1000
for i in xrange(maxiter):
   # your code
   # on success:
     break
else:
   # that algorithm has not finished in maxiter steps! do something accordingly
于 2010-02-14T17:46:17.203 に答える
1

2番目の式はより明示的であり、したがってよりpythonicだと思います。

于 2010-02-14T17:51:16.847 に答える
0

これは単にスタイルの問題であり、プログラミングの初心者なら誰でもどちらのオプションも理解できます。

しかし、2 番目のオプションは、 Python 3 まで可能だった が にTrue割り当てられていない場合にのみ機能します。False

>>> True = False
>>> True
False
于 2010-02-14T17:40:32.537 に答える
0

より良い方法は、条件付きでループから抜け出す "while True" です。

于 2010-02-14T17:59:11.257 に答える