51

ここでの議論によって促された

ドキュメントallは、との動作に相当するコードを提案していますany

同等のコードの動作を定義の一部と見なす必要がありますか、それとも実装で短絡しない方法でそれらを実装できますか?

これは、cpython / Lib / test/test_builtin.pyからの関連する抜粋です。

def test_all(self):
    self.assertEqual(all([2, 4, 6]), True)
    self.assertEqual(all([2, None, 6]), False)
    self.assertRaises(RuntimeError, all, [2, TestFailingBool(), 6])
    self.assertRaises(RuntimeError, all, TestFailingIter())
    self.assertRaises(TypeError, all, 10)               # Non-iterable
    self.assertRaises(TypeError, all)                   # No args
    self.assertRaises(TypeError, all, [2, 4, 6], [])    # Too many args
    self.assertEqual(all([]), True)                     # Empty iterator
    S = [50, 60]
    self.assertEqual(all(x > 42 for x in S), True)
    S = [50, 40, 60]
    self.assertEqual(all(x > 42 for x in S), False)

def test_any(self):
    self.assertEqual(any([None, None, None]), False)
    self.assertEqual(any([None, 4, None]), True)
    self.assertRaises(RuntimeError, any, [None, TestFailingBool(), 6])
    self.assertRaises(RuntimeError, all, TestFailingIter())
    self.assertRaises(TypeError, any, 10)               # Non-iterable
    self.assertRaises(TypeError, any)                   # No args
    self.assertRaises(TypeError, any, [2, 4, 6], [])    # Too many args
    self.assertEqual(any([]), False)                    # Empty iterator
    S = [40, 60, 30]
    self.assertEqual(any(x > 42 for x in S), True)
    S = [10, 20, 30]
    self.assertEqual(any(x > 42 for x in S), False)

短絡動作を強制するために何もしません

4

4 に答える 4

64

The behaviour is guaranteed. I've contributed a patch, which was accepted and merged recently, so if you grab the latest sources you will see that the short-circuiting behaviour is now explicitly enforced.

git clone https://github.com/python/cpython.git
grep Short-circuit cpython/Lib/test/test_builtin.py
于 2013-02-14T01:29:39.380 に答える
12

ドキュメントは言う

"反復可能要素のいずれかの要素が true の場合は True を返します。反復可能要素が空の場合は、False を返します。同等のもの: " (強調は私のもの) ...

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False

any短絡していない場合、投稿されたコードは明らかに短絡しているため、投稿されたコードと同等ではありません。たとえば、必要以上にジェネレーターを消費する可能性があります。それを踏まえると、短絡動作は保証されていると言えます。

についても全く同じ議論が成り立つall

于 2013-02-06T13:28:41.233 に答える
11

ここにたどり着いた場合は、「何か/すべて常に常に短絡しますか?」を探しています。

それらはそうしますが、落とし穴があります: リスト内包表記を使用すると、短絡動作をオーバーライドしているように見える可能性があります。

def hi():
    print('hi')
    return True

>>> any(hi() for num in [1, 2, 3, 4])
hi

>>> any([hi() for num in [1, 2, 3, 4]])
hi
hi
hi
hi

リスト内包表記は any() より先に実行されます。

(注:これはOPの非常に異なる質問には答えません。これは、「すべての短絡python」を検索したときに表示される唯一のstackoverflowページです。)

于 2018-12-03T19:48:38.873 に答える
3

バインドされていないイテラブルが与えられる可能性があるため、短絡する必要があります。短絡していない場合、これは決して終了しません。

any(x == 10 for x in itertools.count())
于 2013-02-06T13:39:55.090 に答える