Is the shortcircuit behaviour of Python's any/all explicit?

后端 未结 4 1544
面向向阳花
面向向阳花 2020-11-28 11:04

Prompted by the discussion here

The docs suggest some equivalent code for the behaviour of all and any

Should the behaviour of the equivalent code be conside

相关标签:
4条回答
  • 2020-11-28 11:42

    The docs say

    "Return True if any element of the iterable is true. If the iterable is empty, return False. EQUIVALENT TO:" (emphasis mine) ...

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

    If any didn't short circuit, it wouldn't be EQUIVALENT to the posted code since the posted code clearly short circuits. You could consume more of a generator than you want to for example. In light of that, I say that the short circuiting behavior is guaranteed.

    The exact same argument could be made for all.

    0 讨论(0)
  • 2020-11-28 11:42

    In case you landed here looking for "do any/all always always short-circuit?"

    They do, but there is a gotcha: using a list comprehension can make it seem like you are overriding the short-circuiting behavior:

    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
    

    The list comprehension executes before any() does.

    (Note: This does not answer the OP's very different question. This is the only stackoverflow page that comes up for me when searching "any all short circuit python.")

    0 讨论(0)
  • 2020-11-28 11:46

    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
    
    0 讨论(0)
  • 2020-11-28 11:50

    It HAS to short circuit, since it could be given an unbound iterable. If it did not short circuit then this would never terminate:

    any(x == 10 for x in itertools.count())
    
    0 讨论(0)
提交回复
热议问题