I typed
print([1,2] and 3)
and the result is
3
How did this happen? Why is the result 3?
I guess [1,2] is considered as True. But I don't know how the backend process works.
When Boolean "and" operator is "True" it return the last/left most "True" value in expression.
>>> print(3 and 5)
5
>>> print((3 and [1,4] and [1,2] ))
[1, 2]
Boolean operator give "False" for 0, when "and" operator result is "False" it return the firstly "False" value in expression.
>>> print([1,2] and 0)
0
>>> z = False
>>> print((3 and z and 0 ))
False
Boolean Operations — and, or, not
These are the Boolean operations, ordered by ascending priority:
Operation
Result
Notes
x or y
if x is false, then y, else x
(1)
x and y
if x is false, then x, else y
(2)
not x
if x is false, then True, else False
(3)
Notes:
This is a short-circuit operator, so it only evaluates the second argument if the first one is false.
This is a short-circuit operator, so it only evaluates the second argument if the first one is true.
not has a lower priority than non-Boolean operators, so not a == b is interpreted as not (a == b), and a == not b is a syntax error.
Please check this official python doc for more information
This Article From Quora says it best:
Python uses and and or operators in a slightly different way.
It doesn’t return pure boolean values (i.e. True or False) as someone
working with a language like Java might expect.
It returns one of the operand based on conditions, and the truth value
of that operand determines the boolean value if used in a conditional
statement.
and:
Return the first Falsy value if there are any, else return the last
value in the expression.
or:
Return the first Truthy value if there are any, else return the last
value in the expression.
and is a Boolean Operator.
It returns the first operand that evaluates to False or the last one if all evaluate to True.
In this case it will return 3. If the list was empty it would return the empty list, as you can see in this example:
>>> [] and 3
[]
Related
str_list = ["Emma", "Jon", "", "Kelly", None, "Eric", ""]
str_list = [x for x in str_list if x]
print(str_list)
Python supports the concepts of "truthy," meaning a value treated as logically true, and "falsey," a value logically treated as false. As it turns out, empty string is falsey, so the if x condition in the list comprehension will exclude empty string values.
Here, checking if x is implicitly looking at bool(x). Specifically, notice that when x is an empty string, bool(x) is false: we say that it is "falsy." You can see this for yourself interactively:
>>> bool("Emma")
True
>>> bool("")
False
>>>
This list comprehension effectively filters out these "falsy" values, or in this case, empty strings.
For more about common truth values and how to customize your own, see the Python docs.
def pos_neg(a, b, negative):
if negative:
return (a < 0 and b < 0)
else:
return ((a < 0 == b > 0) or (a > 0 == b < 0))
so basically I tried some basic problems.
I just started out and went to https://codingbat.com/prob/p162058 to try it and don't understand why if I were to replace the '==' with 'and' it would work? Thanks.
Oh, I got it now, thanks guys. :D
(this python community is fire!!!)
Since you're learning, you might be interested in seeing that this is an equivalent function.
basically it does a bit wise & and returns true if the result is < 0
else a bit wise exclusive or and returns true if the result is < 0
def pos_neg(a , b, negative):
if negative:
return (a & b) < 0 # both sign bits set (i.e. neg), return true
else:
return (a ^ b) < 0 # different signs, return true
In both cases, it is the sign bit of the result that is of concern. If the bit is set then the value will be negative (hence the comparison to < 0)
and is a logical operator and returns true only when both the expressions we are using it on are true.
== is used for comparisons and returns true when both expressions are equal; they don't need to be true.
To give you an example False == False will return True but False and False will return False.
This "==" means equals to, belonging to Python Comparison Operators, used to compare two values.
and language keyword "and" it is for Python Logical Operators used to combine conditional statements.
You should check out this, it may solve others doubts you have.
W3Schools
All your relational operator usages (i.e. a < 0, b < 0, etc.) result to a boolean value and thus these are known as boolean expressions.
When you put a < 0, think of it like a test of: "is a less than 0, true or false?".
So, if both a and b are negative (i.e. less than zero), their expressions will return true.
So on the line return a < 0 and b < 0, replacing and with == is like saying return true == true. Without the change it'd be return true and true.
Note: This does not mean == is the same as and. == checks for equality of the left-hand side to the right-hand side (e.g. 1 == 1) and gives a true or false value depending on the result of equality. and checks for if the left-hand side results to a true statement and if the right-hand side results to a true statement in order to result to a true expression.
I just learned there are truthy and falsy values in python which are different from the normal True and False.
Can someone please explain in depth what truthy and falsy values are? Where should I use them? What is the difference between truthy and True values and falsy and False values?
We use "truthy" and "falsy" to differentiate from the bool values True and False. A "truthy" value will satisfy the check performed by if or while statements. As explained in the documentation, all values are considered "truthy" except for the following, which are "falsy":
None
False
Numbers that are numerically equal to zero, including:
0
0.0
0j
decimal.Decimal(0)
fraction.Fraction(0, 1)
Empty sequences and collections, including:
[] - an empty list
{} - an empty dict
() - an empty tuple
set() - an empty set
'' - an empty str
b'' - an empty bytes
bytearray(b'') - an empty bytearray
memoryview(b'') - an empty memoryview
an empty range, like range(0)
objects for which
obj.__bool__() returns False
obj.__len__() returns 0, given that obj.__bool__ is undefined
As the comments described, it just refers to values which are evaluated to True or False.
For instance, to see if a list is not empty, instead of checking like this:
if len(my_list) != 0:
print("Not empty!")
You can simply do this:
if my_list:
print("Not empty!")
This is because some values, such as empty lists, are considered False when evaluated for a boolean value. Non-empty lists are True.
Similarly for the integer 0, the empty string "", and so on, for False, and non-zero integers, non-empty strings, and so on, for True.
The idea of terms like "truthy" and "falsy" simply refer to those values which are considered True in cases like those described above, and those which are considered False.
For example, an empty list ([]) is considered "falsy", and a non-empty list (for example, [1]) is considered "truthy".
See also this section of the documentation.
Python determines the truthiness by applying bool() to the type, which returns True or False which is used in an expression like if or while.
Here is an example for a custom class Vector2dand it's instance returning False when the magnitude (lenght of a vector) is 0, otherwise True.
import math
class Vector2d(object):
def __init__(self, x, y):
self.x = float(x)
self.y = float(y)
def __abs__(self):
return math.hypot(self.x, self.y)
def __bool__(self):
return bool(abs(self))
a = Vector2d(0,0)
print(bool(a)) #False
b = Vector2d(10,0)
print(bool(b)) #True
Note: If we wouldn't have defined __bool__ it would always return True, as instances of a user-defined class are considered truthy by default.
Example from the book: "Fluent in Python, clear, concise and effective programming"
Truthy values refer to the objects used in a boolean context and not so much the boolean value that returns true or false.Take these as an example:
>>> bool([])
False
>>> bool([1])
True
>>> bool('')
False
>>> bool('hello')
True
Where should you use Truthy or Falsy values ?
These are syntactic sugar, so you can always avoid them, but using them can make your code more readable and make you more efficient.
Moreover, you will find them in many code examples, whether in python or not, because it is considered good practice.
As mentioned in the other answers, you can use them in if tests and while loops. Here are two other examples in python 3 with default values combined with or, s being a string variable. You will extend to similar situations as well.
Without truthy
if len(s) > 0:
print(s)
else:
print('Default value')
with truthy it is more concise:
print(s or 'Default value')
In python 3.8, we can take advantage of the assignment expression :=
without truthy
if len(s) == 0:
s = 'Default value'
do_something(s)
with truthy it is shorter too
s or (s := 'Default value')
do_something(s)
or even shorter,
do_something(s or (s := 'Default value'))
Without the assignment expression, one can do
s = s or 'Default value'
do_something(s)
but not shorter. Some people find the s =... line unsatisfactory because it corresponds to
if len(s)>0:
s = s # HERE is an extra useless assignment
else:
s = "Default value"
nevertheless you can adhere to this coding style if you feel comfortable with it.
Any object in Python can be tested for its truth value. It can be used in an if or while condition or as operand of the Boolean operations.
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.
All other values are considered True -- thus objects of many types are always true.
Operations and built-in functions that have a Boolean result always return 0 or False for false and 1 or True for true, unless otherwise stated.
In case of if (!id) {}
!expr returns false if its single operand can be converted to true; otherwise, returns true.
If a value can be converted to true, the value is so-called truthy. If a value can be converted to false, the value is so-called falsy.
Examples of expressions that can be converted to false are:
null;
NaN;
0;
empty string ("" or '' or ``);
undefined.
Even though the ! operator can be used with operands that are not Boolean values, it can still be considered a boolean operator since its return value can always be converted to a boolean primitive. To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double NOT operator or the Boolean constructor.
Example:
n1 = !null // !t returns true
n2 = !NaN // !f returns true
n3 = !'' // !f returns true
n4 = !'Cat' // !t returns false
While in case of if (id != null) {} it will only check if the value in id is not equal to null
reference https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_NOT
Falsy means something empty like empty list,tuple, as any datatype having empty values or None.
Truthy means :
Except are Truthy
I found some strange behavior in python. Possibly my logic is not correct.
1 and 2 and 3 in range(5)
Expected: True
Outcome: True
2 and 1 and 99 in range(5)
Expected: False
Outcome False
2 and 1 and 0 in range(5)
Expected: True
Outcome: True
Now the tricky one:
0 and 1 and 2 in range(5)
Expected: True
Outcome: 0
I am sure there is someone who makes me find my logical error.
In each expression, only the last number is checked against the range. The previous ones are evaluated "as is". In python, the expression if i: evaluates to True if i is not 0.
The value returned from the expressions (boolean or int) depends on what the conditions are. If you leave just 1 and 2 for example, the result will be the last int. However, since you have the v in range(n) expression, which returns True or False, the result is cast into a boolean value.
Now, due to short-circuit evaluation, in the last case, only the zero gets evaluated. So the result is not cast into a boolean and 0 is returned.
Edit: After reading the comments, it becomes clear that you want to check if k number exist in range(n). For that, you cannot use the simple expressions you've shown. You need to check if every individual value exists in the range. One - inefficient - approach would be this
if all([v in range(n) for v in values]):
print("All values exist in the range")
Edit 2 (by #Pranav Hosangadi)
Side note:
Since the all() function takes generator expressions, you can avoid the list-comprehension altogether. When you do this, the generator expression will only calculate as many items as needed for the all() to short-circuit. On the other hand, the list-comprehension approach will calculate all elements in the list, and then run all() on that list. Here's a simple example:
l = [100] * 10000
l[-1] = 0
def f1(): # Using generator
return all(li == 0 for li in l)
def f2(): # Using list comp
return all([li == 0 for li in l])
Now for the generator-expression approach, all() needs to calculate only the first element to know that it will short-circuit to False. However, the list-comprehension approach calculates all elements of the list first. All but the last element of this list are False. Then, all() takes this list and short-circuits at the first element. Running some timing on these functions:
import timeit
timeit.timeit('f1()', setup='from __main__ import f1, l', number=10000)
# Out: 0.006381300001521595
timeit.timeit('f2()', setup='from __main__ import f2, l', number=10000)
# Out: 5.257489699986763
f1() is significantly faster than f2().
I've written some code and here's a short bit
x = ['apple, iphone','samsung, galaxy','oneplus, 10pro']
print('apple' in x)
how do I get this statement as true, since apple already exists in x, I still keep getting the False as the boolean value.
When the in operator is applied to a list like you have here it looks for an exact match in the list. Your code is returning false because 'apple' isn't in the list, 'apple, iphone' is. To check each element in the list for the substring 'apple' you could use list comprehension. Something like:
x = ['apple, iphone','samsung, galaxy','oneplus, 10pro']
print(True in ['apple' in s for s in x])
What the second line does is use list comprehension to build a list of booleans indicating if the substring 'apple' is in that element. Then it checks if True is in the resulting list.
or instead of using the in operator:
x = ['apple, iphone','samsung, galaxy','oneplus, 10pro']
print(any(['apple' in s for s in x]))
The any built-in function returns true if any element in an iterable is True.
x = ['apple, iphone','samsung, galaxy','oneplus, 10pro']
print(True in ('apple' in d for d in x))
Maybe use a function like this:
IsItemInList(item, list):
for x in list:
if x == item:
return True
return False
Pretty sure theres a much cleaner way to do this but that was my first guess. As we know, the first is mostly the worst.