Why don't all () stop at the first False element?

From docs , all equivalent to:

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

Then why do I get this conclusion:

 # expecting: False $ python -c "print( all( (isinstance('foo', int), int('foo')) ) )" Traceback (most recent call last): File "<string>", line 1, in <module> ValueError: invalid literal for int() with base 10: 'foo' 

When:

 # expecting: False $ python -c "print( isinstance('foo', int) )" False 
+4
source share
4 answers

Arguments are evaluated before the function is called. In this case, you first need to create a tuple that you pass to all .

all never possible to check them, before that there was an exception.

 >>> int('foo') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: invalid literal for int() with base 10: 'foo' 
+5
source

One (rather ugly) way to get the right behavior through lambdas:

 all(f() for f in (lambda: isinstance('foo', int), lambda: int('foo'))) 
+7
source

Your intuition regarding all true; you only need to complicate the task of creating a lazy sequence a bit. For instance:

 def lazy(): yield isinstance("foo", int) # False yield int("foo") # raises an error, but we won't get here >>> all(lazy()) False >>> list(lazy()) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in lazy ValueError: invalid literal for int() with base 10: 'foo' 
+2
source

If the desire to stop evaluating after the first False condition is specifically designed for type checking, something like this will work better:

 if not isinstance(other, MyClass): return False else: return all((self.attr1 == other.attr2, self.attr2 == other.attr2)) # etc. 

Simplified version of @catchmeifyoutry :

 return isinstance(other, MyClass) and all((self.attr1 == other.attr2, self.attr2 == other.attr2)) # etc. 
+1
source

Source: https://habr.com/ru/post/1488698/


All Articles