Understanding Python Operators and Expressions
Today, we’ll dive into the world of operators and expressions, exploring their intricacies and learning how to wield them effectively in your code.
Variable References in Python
In Python, variables are references to objects. Let’s take a look at an interesting aspect of variable assignment:
a = b = c = 300
print(a, b, c) # Output: 300 300 300
Here, a
, b
, and c
are references to the same integer object with the value 300.
m = 300
n = 300
print(id(m))
print(id(n))
# Output:
# 2429504311632
# 2429504312240
In this case, m
and n
reference different objects. However, for integers in the range [-5, 256], Python optimizes memory usage by reusing the same objects.
m = 30
n = 30
print(id(m))
print(id(n))
# Output:
# 2429435145424
# 2429435145424
Here, m
and n
reference the same object because the value falls within the optimization range.
Arithmetic Operators
Python provides various arithmetic operators for numerical operations:
a = 9
b = 4
add = a + b
print("addtion of numbers:",add) # Addition: 13
sub = a - b
print("subtraction of numbers:",sub) # Subtraction: 5
mul = a * b
print("Multiplication of number:",mul) # Multiplication: 36
div1 = a / b
print("Division(float) of numbers:",div1) # Division(float): 2.25
div2 = a // b
print("Division(floor) of number:",div2) # Division(floor): 2
mod = a % b
print("Modulo of both number :",mod) # Modulo: 1
# When the result of floor division (//) is positive, it is as though the fractional portion is truncated off,
# leaving only the integer portion. When the result is negative, the result is rounded down to the next smallest
# (greater negative) integer:
print(10 / 4) # 2.5
print(10 // 4) # 2
print(10 // -4) # -3
print(-10 // 4) # -3
print(-10 // -4) # 2
Relational Operators
a = 1
b = 2
print(a > b)
print(a < b)
print(a == b)
print(a != b)
print(a >= b)
print(a <= b)
# Output:
# False
# True
# False
# True
# False
# True
x = 1.1 + 2.2
print(x) # 3.3000000000000003
# value stored internally for a float object may not be precisely what you’d think it would be. For that reason,
# it is poor practice to compare floating-point values for exact equality.
x = 1.1 + 2.2
x == 3.3 # False
# The preferred way to determine whether two floating-point values are “equal” is to compute whether they are
# close to one another, given some tolerance
tolerance = 0.00001
x = 1.1 + 2.2
abs(x - 3.3) < tolerance # True
Logical Operators
Logical operators perform logical operations:
print(True and True)
print(False and False)
print(True and False)
print(False and True)
print(True or True)
print(False or False)
print(True or False)
print(False or True)
print(not True)
print(not False)
# Output:
# True
# False
# False
# False
# True
# False
# True
# True
# False
# True
Bitwise Operators
Bitwise operators operate on binary representations of numbers:
a = 1 # 0001
b = 2 # 0010
print(a & b) # Bitwise AND: 0000
print(a | b) # Bitwise OR: 0011
print(~a) # Bitwise NOT: -2
print(a ^ b) # Bitwise XOR: 0011
print(a >> 2) # Bitwise right shift: 0000
print(a << 2) # Bitwise left shift: 0100
Assignment Operators
Assignment operators provide shortcuts for updating variables:
x = 5
x += 3
x -= 3
x *= 3
x /= 3
x %= 3
x //= 3
x **= 3
# Output:
# 5
# 8
# 5
# 15
# 5.0
# 2.0
# 0.0
# 0.0
Identity Operators
Identity operators check if two values are located in the same part of memory:
a1 = 1
b1 = 1
a2 = 'rajsingh'
b2 = 'rajsingh'
a3 = [1, 2, 3]
b3 = [1, 2, 3]
print(a1 is not b1)
print(a2 is b2)
print(a3 is b3)
# Output:
# False
# True
# False
# when you make an assignment like x = y, Python merely creates a second reference to the same object
x is y # False
Membership Operators
Membership operators in
and not in
are used to test if a value is present in a sequence:
x = 'Raj singh Rajpoot'
y = {1:'a',2:'b'}
print('R' in x) # Outputs: True
print('raj' not in x) # Outputs: True
print('Raj' not in x) # Outputs: False
print(1 in y) # Outputs: True
print('b' in y) # Outputs: False
Any / All
any()
returns true if any of the items in the iterable is true, and all()
returns true if all items in the iterable are true:
print (any([False, False, False, False])) # Outputs: False
print (any([False, True, False, False])) # Outputs: True
print (all([True, True, True, True])) # Outputs: True
print (all([False, True, True, False])) # Outputs: False
print (all([False, False, False])) # Outputs: True
Chained Comparison Operators
Chained comparison operators allow you to chain multiple comparison operators together:
print(1 < 2 < 3) # Outputs: True
print(1 < 2 and 2 < 3) # Outputs: True
Ternary Condition
The ternary condition allows you to write conditional expressions in a concise form:
# <expression_if_true> if <condition> else <expression_if_false>
[a if a else 'zero' for a in [0, 1, 0, 3]] # Outputs: ['zero', 1, 'zero', 3]
Operator Precedence
Operator precedence determines the order in which operators are evaluated:
print(2 * 3 ** 4 * 5) # Outputs: 810
print(2 * 3 ** (4 * 5)) # Outputs: 6973568802
Evaluation of Non-Boolean Values in Boolean Context
In Python, non-boolean values can be evaluated in a boolean context:
print(bool(0), bool(0.0), bool(0.0+0j)) # Outputs: False False False
print(bool(-3), bool(3.14159), bool(1.0+1j)) # Outputs: True True True
print(bool(''), bool(""), bool("""""")) # Outputs: False False False
print(bool('foo'), bool(" "), bool(''' ''')) # Outputs: True True True
print(type([]))
print(bool([])) # Outputs: False
print(type([1, 2, 3]))
print(bool([1, 2, 3])) # Outputs: True
print(bool(None)) # None is always false: # Outputs: False
x = 3
print(bool(x)) # True
y = 0.0
print(bool(y)) # False
x = 3
y = 4
print(x or y) # 3
x = 0.0
y = 4.4
print(x or y) # 4.4
x = 3
y = 4
print(x and y) # 4
x = 0.0
y = 4.4
print(x and y) # 0.0
Short-Circuit Evaluation
Short-circuit evaluation allows for efficient evaluation of boolean expressions:
a = 0
b = 1
print(a != 0 and (b / a) > 0) # Outputs: False
string = 'foo bar'
s = string or '<default_value>'
print(s) # Outputs: 'foo bar'
string = ''
s = string or '<default_value>'
print(s) # Outputs: '<default_value>'
Assertion Example
The assert
statement is used for debugging purposes to assert that a certain condition is true. If the condition is false, an AssertionError
is raised:
x = "hello"
assert x == "hello" # No output if condition is True
assert x == "goodbye" # AssertionError raised if condition is False
Conclusion
Understanding Python’s memory management and various operators is crucial for writing efficient, error-free code. You can optimize your Python programs for better performance and readability by leveraging these concepts.