3

ループがまったく実行されていないかどうかを確認するにはどうすればよいですか?

これはどういうわけか私には複雑すぎるように見えます:

x = _empty = object()
for x in data:
    ... # process x
if x is _empty:
    raise ValueError("Empty data iterable: {!r:100}".format(data))

もっと簡単な解決策はありませんか?

上記のソリューションは、curiousefficiency.orgからのものです。

アップデート

  • データにはNoneアイテムを含めることができます。
  • data は反復子であり、2 回使用したくありません。
4

7 に答える 7

3

「走ったことがない」ということdataは、要素がなかったということですか?

その場合、最も簡単な解決策は、ループを実行する前に確認することです。

if not data:
    raise Exception('Empty iterable')

for x in data:
    ...

ただし、以下のコメントで述べたように、ファイル、ジェネレーターなどの一部のイテラブルでは機能しないため、慎重に適用する必要があります。

于 2015-02-02T10:14:03.320 に答える
2

元のコードが最適です。

x = _empty = object()

_emptyをセンチネル値と呼びます。Python では、 を使用してセンチネルを作成するのが一般的です。これは、 の唯一の目的がダミー値であるobject()ことを明確にするためです。_emptyただし、空の list など、任意の変更可能なものを使用できます[]

可変オブジェクトは、 と比較したときに常に一意であることが保証されているため、やisなどの不変オブジェクトとは異なり、センチネル値として安全に使用できます。None0

>>> None is None
True
>>> object() is object()
False
>>> [] is []
False
于 2015-02-02T11:06:05.587 に答える
1

次の簡単な解決策は、あらゆる iterable で機能します。これは、(最初の) 要素があるかどうかを確認し、存在する場合は反復を続けることができるという考えに基づいています。結果はより明確です。

import itertools

try:
    first_elmt = next(data)
except StopIteration:
    raise ValueError("Empty data iterator: {!r:100}".format(data))

for x in itertools.chain([first_elmt], data):
    …

dataPS:それがイテレータであると仮定していることに注意してください(質問のように)。単に iterable である場合、コードは ondata_iter = iter(data)ではなくon で実行する必要がありますdata(そうしないと、dataがリストの場合、ループは最初の要素を複製します)。

于 2015-02-02T10:53:44.253 に答える
0

loop_flagデフォルトを False として追加できます。ループが実行されたら、True に変更します。

loop_flag = False
x = _empty = object()

for x in data:
    loop_flag = True
    ... # process x

if loop_flag:
    print "loop executed..."
于 2015-02-02T10:08:05.133 に答える