The differences' between the operator "==" and "=". When would each be used? Why would each be used?
In python and other languages like C,
"=" is a assignment operator and is used to assign a value to a variable.
Example: a=2 # the value of a is 2
whereas "==" is Comparison operator and is used to check whether 2 expressions give the same value .Equality check returns true if it succeeds and else return false.
Example: a=2 b=3 c=2
a==b (#false because 2 is not equal to 3)
a==c (#true because 2 is equal to 2)
= is used for assignment: e.g.: apple = 'apple'.
It states what is what.
== compares one value to another. Is 5 equal to 5 should be written like this: 5 == 5
An == expression evaluates to true, is an equality operator.
== has the value of two operands are equal make the condition or statement true.
= is an expression of assignment operator to the symbol of variables, arrays, objects.
Both operators are very important, and they work in different ways in every equivalent object. Their behavior in their operation is based on the identity of objects. Are reflation of their variables.
When using == in compares the values of two objects example having two cars from the same company and have the same identity and features and same looks.
The rule implies that the statement and condition to be trues
To use = operator is when to evaluate variables in an expression if both sides of the operator mean same or the objects are same if not same its expression will be false and if true the expressions or objects are same.
Related
This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 5 years ago.
I am trying to add multiple 'or' clauses to a python if statement using list comprehension. My code is shown below. I would like to keep the list comprehension. In terms of pseudocode, the logic would simply be:
Alive_Beatles = each name that contains '(Beatle)' and either ('Paul', 'Yoko' or 'Ringo')
The code only returns Paul and skips Ringo and Yoko.
Names = ["John Lennon (Beatle)", "Paul McCartney (Beatle)", "Ringo Starr (Beatle)", "Yoko Ono (Beatle)", "Mick Jagger (Rolling Stone)", "Brian Jones (Rolling Stone)", "Alex Jones (na)", "Adam Smith (na)"]
Alive_Beatles = [n for n in Names if ("Beatle" and ("Paul" or "Ringo" or "Yoko")) in n]
print Alive_Beatles
You need to test each name explicitly if it's in n:
[n for n in Names if ("Beatle" in n and ("Paul" in n or "Ringo" in n or "Yoko" in n))]
Otherwise the and and or use the truth value of you search strings (and each non-empty string is always True) and finally tests if Paul in n (the first truth value of the ors).
The documentation explicitly mentions this:
4.2. 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:
(1) This is a short-circuit operator, so it only evaluates the second argument if the first one is false.
(2) This is a short-circuit operator, so it only evaluates the second argument if the first one is true.
(3) 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.
So "Beatle" and (...) evaluates according to (2) to the second argument because "Beatle" is truthy and according to (1) it evaluates to the first argument of the chained ors: "Paul" because it's also truthy.
This doesn't do what you expect because the expression
("Paul" or "Ringo" or "Yoko")
evaluates to "Paul". Type it in at an interpreter prompt to confirm this.
And even that only seems to work because
("Beatle" and ("Paul" or "Ringo" or "Yoko"))
also evaluates to "Paul".
The most straightforward solution is to just list
[n for n in Names if "Beatle" in n and ("Paul" in n or "Ringo" in n or "Yoko" in n)]
But you could use any to get a bit closer to what you tried initially:
[n for n in Names if "Beatle" in n and any(x in n for x in ("Paul", "Ringo", "Yoko"))]
Kindly help me understand why this works. The code below lists duplicates in an iterable. However, the use of the or operator behaves like the else in an if..else statement..
j = set()
my_list = [1, 2, 3 ,3 , 3 ,4, 4]
j_add = j.add
twice = set(x for x in my_list if x in j or j_add(x))
print list(twice)
Would expect the line to be:
twice = set(x for x in my_list if x in j else j_add(x))
Thought or returns a boolean not a value
The or operator returns the last evaluated argument, which may or may not be a Boolean.
This behavior is explained in the Documentation:
Note that neither and nor or restrict the value and type they return to False and True, but rather return the last evaluated argument. This is sometimes useful, e.g., if s is a string that should be replaced by a default value if it is empty, the expression s or 'foo' yields the desired value.
Of course, it helps to remember what is interpreted as false and what is interpreted as true:
[T]he following values are interpreted as false: False, None, numeric zero of all types, and empty strings and containers (including strings, tuples, lists, dictionaries, sets and frozensets). All other values are interpreted as true.
So in the expression:
A = B or C
As #MartijnPieters points out in a comment, an or expression short-circuits. If the first argument (B in this case) is interpreted as true, the entire expression must be true so the second argument (C) is never evaluated. Therefore the first argument (B) is "the last evaluated argument" and is what is returned. However, if the first argument (B) is interpreted as false, the second argument (C) must still be evaluated to determined the truthiness of the expression (no short-circuit takes place). In that case, "the last evaluated argument" is the second argument (C), which is returned regardless of whether the expression evaluates true or false.
It effectively accomplishes the same as the Conditional Expression:
A = B if B else C
However, Conditional Expressions were only added to Python in version 2.5, while the Boolean Operator behavior has existed from the beginning (or at least for a very long time). Most seasoned Python programmers will easily recognize and are in the habit of using A = B or C. Conditional Expressions are commonly reserved for more complex conditions that won't work with a simple or (for example in A = B if X else C the condition is not based on the truthiness of B but X, which could be anything from a simple value to a complex expression).
However, you need to be careful because, as JaredGoguen points out in his answer, changing the or to an else in the OP's sample actually changes the behavior of the code. That code was written to depend on this specific behavior of the or operator. You can't just replace any use of or for assignment with a Conditional Expression. Additional refactoring may be needed as well.
I might make a value judgment here and say that this is not good code because it is using the short-circuiting behavior of or to produce a side-effect.
Consider the given conditional: if x in j or j_add(x).
When x in j, the or short-circuits, skips the j_add(x) part of the conditional, and evaluates as True.
When x not in j, the statement j_add(x) is checked for its truthiness. This method returns None, which is falsy, and so or evaluate as False.
So, the entire conditional will evaluate the same as x in j. However j_add(x) has the side-effect of adding x to j! This side-effect is being exploited in order to record the unique members my_list in a quick-and-dirty comprehension.
Changing the or to an else would still construct j as desired, but it would inappropriately add None, the return value of j_add(x), to twice.
Does Python have augmented assignment statements corresponding to its boolean operators?
For example I can write this:
x = x + 1
or this:
x += 1
Is there something I can write in place of this:
x = x and y
To avoid writing "x" twice?
Note that I'm aware of statements using &= , but I was looking for a statement that would work when y is any type, not just when y is a boolean.
The equivalent expression is &= for and and |= for or.
>>> b = True
>>> b &= False
>>> b
False
Note bitwise AND and bitwise OR and will only work (as you expect) for bool types. bitwise AND is different than logical AND for other types, such as numeric
>>> bool(12) and bool(5) # logical AND
True
>>> 12 & 5 # bitwise AND
4
Please see this post for a more thorough discussion of bitwise vs logical operations in this context.
No, there is no augmented assignment operator for the boolean operators.
Augmented assignment exist to give mutable left-hand operands the chance to alter the object in-place, rather than create a new object. The boolean operators on the other hand cannot be translated to an in-place operation; for x = x and y you either rebind x to x, or you rebind it to y, but x itself would not change.
As such, x and= y would actually be quite confusing; either x would be unchanged, or replaced by y.
Unless you have actual boolean objects, do not use the &= and |= augmented assignments for the bitwise operators. Only for boolean objects (so True and False) are those operators overloaded to produce the same output as the and and or operators. For other types they'll either result in a TypeError, or an entirely different operation is applied. For integers, that's a bitwise operation, sets overload it to do intersections.
Can someone explain how these results are possible (python 2.6):
>>> 1<3>2
True
>>> (1<3)>2
False
>>> 1<(3>2)
False
I would think that one of the last two would match the first one, but apparently the operators in the first statement is somehow linked?!
Your first example shows comparison chaining. 1<3>2 means 1<3 and 3>2 (except each expression is evaluated only once). This applies to all comparison operators in Python.
Your second two examples force one comparison to be evaluated first, resulting in a boolean value which is then compared with the remaining integer.
In your first case 1<3>2 1 is actually lesser than 3 and 3 is greater than 2, so True.
In your second case (1<3)>2 (1<3) evaluates as True that represented as 1, so 1 is not greater than 2.
In your third case 1<(3>2), 1 is not lesser than True that represented as 1.
The last two statements compare booleans against an integer:
>>> True > 2
False
>>> 1 < True
False
The first statement is comparison chaining, which works for all boolean comparisons in Python. Note from the documentation:
Comparisons yield boolean values: True or False.
By placing parts of your expression in brackets, those parts get evaluated first and you end up with comparing integers and booleans.
As per docs,
Unlike C, all comparison operations in Python have the same priority, which is lower than that of any arithmetic, shifting or bitwise operation. Also unlike C, expressions like a < b < c have the interpretation that is conventional in mathematics:
comparison ::= or_expr ( comp_operator or_expr )*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="
| "is" ["not"] | ["not"] "in"
Comparisons yield boolean values: True or False.
Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).
I have some code here:
m = None
n = None
if not m:
print "Something happens"
>>> Something happens
if I do:
if not m and n:
print "Something happens"
Nothing happens.
But I can do:
m, n = 1,2
if m and n:
print "Something happens"
>>> Something happens
Why are if and if not handled the same way? Does 'if not', not take 'and' statements?
Thank you
You have an operator precedence problem.
if not m and n is equivalent to if (not m) and n. What you want is if not m and not n or if not (m or n).
See also: De Morgan's Laws
I think you are looking for this article: Truth Value Testing
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.
All other values are considered true — so 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. (Important exception: the Boolean operations or and and always return one of their operands.)
Especially the next chapter explains your case (Boolean Operations — and, or, not):
not has a lower priority than non-Boolean operators
not applied to its closet operand. You wrote if not m and n where not applies to m which is True, and because of and, n is evaluate to False, hence the entire statement is evaluated to False.