Operators and Expressions 2
Okay, let’s continue our discussion on Operators and Expressions, building upon the foundational concepts we covered previously. The sources provide further details and examples across various operator types and how they form expressions.
As established, in Python, expressions are combinations of values, variables, and operators that are evaluated by the interpreter to produce a value. Operators are special symbols or keywords that perform computations or actions on operands.
The sources categorize operators into several types:
Arithmetic Operators: These perform mathematical operations.
+
: Addition. For numbers, it adds. For sequences like strings or lists, it performs concatenation.-
: Subtraction. For numbers, it subtracts.*
: Multiplication. For numbers, it multiplies. For sequences, it performs repetition./
: Division. In Python 3.0, this performs true division, keeping fractional remainders. In Python 2.6, it performed classic division, truncating for integers.//
: Floor Division. This divides and truncates fractional remainders, resulting in the integer quotient.%
: Modulus. This divides the left operand by the right and returns the remainder.**
: Exponentiation (power).x ** y
calculates x raised to the power of y. Note that^
is a bitwise operator in Python, not exponentiation.- There are also unary
+
and-
for identity and negation.
Comparison (Relational) Operators: These compare values and return a Boolean result (
True
orFalse
).==
: Equal value.!=
: Not equal value. Python 2.6 also used<>
for not equal, but this was removed in Python 3.0.>
: Greater than.<
: Less than.>=
: Greater than or equal to.<=
: Less than or equal to.- Comparison operators can be chained. For example,
X < Y < Z
is evaluated similarly toX < Y and Y < Z
. If all relational operators give a true result, the chain is true. - In Python 3.0, nonnumeric mixed-type magnitude comparisons are generally not allowed and raise exceptions, unlike in Python 2.x. Magnitude comparisons for dictionaries are also no longer supported in Python 3.0, though equality tests still are.
Assignment Operators: Used to assign values.
=
: Basic assignment.- Augmented assignment operators (
+=
,-=
,*=
,/=
,%=
,**=
,//=
, etc.) provide a shorthand. For instance,x += 1
is equivalent tox = x + 1
. These work on any type that supports the implied binary expression.
Logical Operators: These combine Boolean expressions using the keywords
and
,or
, andnot
.and
: True if both operands are true.or
: True if either operand is true.not
: Reverses the logical state of the operand.- While comparison operators return
True
orFalse
(which are essentially custom versions of integers 1 and 0), theand
andor
operators can return an object (either the left or right operand), not necessarily justTrue
orFalse
. In a Boolean context (like anif
statement), a nonzero number or a nonempty collection object is considered true.
Membership Operators:
in
andnot in
. These test if a value is present in a sequence (like strings, lists, or tuples) or a set.Identity Operators:
is
andis not
. These test if two variables point to the same object in memory, which is a stricter test than==
. For example,True is 1
isFalse
, butTrue == 1
isTrue
.Bitwise Operators: These operate on the individual bits of integers (
&
,|
,^
,~
,<<
,>>
).Other Operators/Operations:
- Indexing (
[]
). Used for accessing elements in sequences or mappings. - Slicing (
[:]
). Used for extracting subsequences from sequences. Python 3.0 allows extended slicing with three parts:X[I:J:K]
. - Call (
()
). Used to invoke functions, methods, or classes. - Attribute reference (
.
). Used to access attributes or methods of objects.
- Indexing (
Operator Precedence: When an expression includes multiple operators, Python follows operator precedence rules to determine the order of evaluation.
- Parentheses (
()
) have the highest precedence and can override the default order. Expressions within parentheses are evaluated first. - Exponentiation (
**
) is next. - Multiplication (
*
), Division (/
,//
), and Modulus (%
) have higher precedence than Addition (+
) and Subtraction (-
). - Operators at the same precedence level are generally evaluated from left to right, except for exponentiation.
- It is often good practice to use parentheses for clarity even when not strictly required by precedence. For example,
2 * 3 + 4
evaluates to 10 because multiplication happens first, while2 * (3 + 4)
evaluates to 14 because parentheses force the addition first.
Expressions and Statements:
Expressions can appear as statements. Common forms of expression statements include calling functions and methods. In Python 3.0, the print()
function is typically used as an expression statement. Expressions typed directly into the interactive interpreter are also expression statements.
Operators and Data Types:
The behaviour of an operator depends on the type of object it is applied to. For instance, +
performs addition on numbers but concatenation on strings, and *
performs multiplication on numbers but repetition on strings. Some operations like indexing ([]
) and slicing ([:]
) are specifically defined for sequence types like strings, lists, and tuples.
Operator Overloading: Classes in Python can intercept and respond to operators by defining special methods (often starting and ending with double underscores). This is known as operator overloading.
- For example, defining
__add__(self, other)
in a class allows instances of that class to be used with the+
operator. - The
__init__
method, called when an object is created (e.g.,X = Class(args)
), is the most commonly used operator overloading method. - Methods like
__getitem__
and__setitem__
can be defined to support indexing and slicing ([]
) for custom objects. __str__
and__repr__
handle how objects are displayed when printed or represented.- Methods like
__bool__
or__len__
(in Python 2.6,__nonzero__
) determine how an object evaluates in a Boolean context. - Operator overloading is useful when a custom object needs to behave like a built-in type (emulating its interface) or when the operations naturally map to the object’s purpose, such as adding vector objects. Python often tries a specific overloading method first and falls back to a more general one if needed; for instance, iteration might try
__iter__
before__getitem__
, and in-place addition (+=
) tries__iadd__
before__add__
.