Reputation: 51
The following codes
multiples = []
for i in range(1,1000):
if i % 3 == 0 or i % 5 == 0:
multiples.append(i)
addition = sum(multiples)
print addition
and
print(sum([i for i in range(1, 1000) if not (i%3 and i%5)]))
do the same thing.
Now how does the if not
part compute in the second code?
What I'm saying is, in the first code the i % 3 == 0 or i % 5 == 0
had to be exclusively stated whereas the same thing is achieved on the second code without the == 0
.
Upvotes: 1
Views: 1054
Reputation: 140188
and
and or
are boolean operators, not logical &
and |
. So writing
a == 0 or b == 0
is the same as writing
not a or not b
So they do the same thing
As a conclusion, the best way is to avoid negations in your conditions, don't create extra list comprehension but use generator comprehension instead, and I wouldn't mind testing against zero instead of using not
since they're integers after all. I would do this:
print(sum(i for i in range(1, 1000) if i%3==0 or i%5==0))
Upvotes: 2
Reputation: 4086
In Python every object has a boolean value.
In the case of integers any of them is True
except 0
.
So in your case when number i
can be divided by 3
the expression i % 3
will be 0
. But we know that 0
is False
. The not
operator will negate this expression so not False
will become True
.
The same holds for not i % 5
as well.
Hope it helps.
Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean operations below. The following values are considered false:
None
False
zero of any numeric type, for example, 0, 0L, 0.0, 0j.
any empty sequence, for example, '', (), [].
any empty mapping, for example, {}.
instances of user-defined classes, if the class defines a nonzero() or len() method, when that method returns the integer zero or bool value False. [1]
All other values are considered true — so objects of many types are always true.
See also: https://docs.python.org/2/library/stdtypes.html
Upvotes: 1
Reputation: 227240
Using De Morgan's laws:
i % 3 == 0 or i % 5 == 0
is the same as:
not (i % 3 != 0 and i % 5 != 0)
And in python, when converting a number to a boolean, any non-zero value becomes True
.
So instead of doing i % 3 != 0
in the if
, you can just use i % 3
, because if it's 0
it'll be False
and if it's non-zero it'll be True
.
Here's python's truth table: https://docs.python.org/3.6/library/stdtypes.html#truth
P.S. sum()
can take a generator as an argument, so you can actually just do:
sum(i for i in range(1, 1000) if not (i%3 and i%5))
Upvotes: 12
Reputation: 159
In Python 0
is usual interpreted as false. So in the first code block i % 3 == 0
is effectively equivalent to not i % 3
. Examples from command line:
>>> 6 % 3 == 0
True
>>> not 6 % 3
True
>>> 7 % 3 == 0
False
>>> not 7 % 3
False
This shortcut of 0 === false
appears in many languages and can be a bit confusing if you're not used to it.
Upvotes: 1
Reputation: 63
This is an effect of the way Python converts integers to booleans. The result of i % 3
is 0, 1, or 2, depending on the value of i
. In Python 3.x (and by default also in Python 2.x, unless you've reassigned them) all non-zero integers evaluate to False
and zero evaluates to True
.
Thus if not (i % 3)
will evaluate (i % 3)
to an integer 0, 1, or 2, and then not
will convert these to False
, True
, True
.
Upvotes: 1
Reputation: 353
see, i % 3 == 0 return true if the condition satisfy. Now, in python suppose:
i = 6
6 % 3 = 0 and 0==0 is true
There fore the result will be true. In the second case
6 % 3 = 0.
Now, in boolean 0 means false. So by using not it means not false, i.e, true.
Upvotes: 0