Expression and Statement¶
- Expression
- Operator
- Statement
Expression¶
An expression is a code construct that is evaluated to a value. A code construct is a piece of code. Following are some common expressions:
- An object or a declared variable, such as:
3
,Hi
,x
,[1, 2, 3]
. - A computation using operators, such as
3 + 5
,x < y < z
. - A function call, such as
len("hello")
,math.pow(3, 2)
. - Functions defined inside types are called methods. A method call is an expression. For example:
"hello".upper()
,[1, 2, 3].pop()
.
Evaluation¶
Evaluation refers to the process that Python interpreter generates the final object of an expression.
Expressions have a common characteristic: the evaluation of the code construct generates a single object.
An object may have a single value such as 3
or multiple values like a list or a tuple.
An expression may have nested expression. For example, a list or a tuple may have other tuple or list or dictionary as its element. There is no limit on the nested levels.
Python evaluates expressions from left to right.
Expression Examples¶
3
is an literal expression, evaluated to3
3 + 5
is an addition operation expression, evaluated to8
len("hello")
is a function call expression, evaluated to5
math.pow(3, 2)
is an method call expression. evaluated to9
len("hello"), math.pow(3, 2)
is an expression that has two nested evaluation, the final evaluation result is a tuple of(5, 3)
.
There are other code constructs that are expressions. They will be introduced later.
Operator¶
An operator is a special symbols that perform operations on values and variables.
A high-level programming language like Python has many built-in operators that make the language simple and easy to understand. For example, very few programming languages have built-in support for chained comparison like x < y < z
or matrix multiplication operation with @
. Python allows both, though matrix data types are not provided by third party libraries.
The data that an on operator acts on are called operands. An operator may take one operand (unary operator), two operands (binary operator), or three operands (ternary operator).
Python has 7 types of operators.
Types of Operators¶
1 Arithmetic Operators
2 Relational Operators
3 Logical (Boolean) Operators
4 Membership Operators
5 Identity Operators
6 Bitwise Operators
7 Assignment Operators
# 1 Arithmetic Operators, evaluated to a number
# if there is a float number operand, the result is a float number
-5 # unary negation: -2
5 + 3.5 # Addition: 8.5
5 - 3 # Subtraction: 2
5 * 1.5 # multiplication: 7.5
5 / 2.0 # division: 2.5
5**3.5 # exponential: 279.5084971874737
5 // 3 # floor division or quotient: 1
5 % 3 # modulus or remainder: 2
# @ is a matrix multiplication operator used by 3rd party libraries
# 2 Relational Operators, evaluated to a boolean value of True or False
3 == 5 # equal to: False
3 != 5 # not equal to: True
3 > 5 # greater than: False
3 < 5 # less than: True
3 >= 5 # greater than or equal to: False
3 <= 5 # less than or equal to: True
3 Logical Operators¶
Also called Boolean
operators. there are three of them: not
, and
, and or
. There are four important details for boolean operators:
- all Python objects can be
Truthy
orFalsy
. not
is a unary boolean operator, it always returns aTrue
orFalse
.- The return value of
and
andor
is determined by their operands. and
andor
operations support short circuiting.
Truthy and Falsy¶
All Python objects can be Truthy
or Falsy
, used as True
or False
in places where a boolean value is required. For example, logical operation and branching code.
You can find the Truthy
or Falsy
value using the built-in function bool()
. Empty values such as 0
, None
, empty list []
, empty tuple ()
and empty dictionary {}
are Falsy
. Most values are Truthy
.
bool([]) # False
bool(3) # True
not(3) # negation operation:False
not(3 == 5) # negation operation: True
not(True) # negation operation:False
and
and or
Logical Operation¶
The evaluation rules are:
x or y
, ifx
isTrue
orTruthy
, thenx
, elsey
x and y
, ifx
isFalse
orFalsy
, thenx
, elsey
If it is confusing, use if/else
statement.
(3 == 5) and (3 != 5) # False
(3 == 5) or (3 != 5) # True
3 or 5 # 3
3 and 5 # 5
0 and "hi" # 0
0 or "hi" # "hi"
Short-circuiting¶
Python supports short-circuiting in and
/or
operations: if it can determine the result from the left part, it doesn't evaluate the later part.
# short-circuiting in and/or
def demo_true():
print("True")
return True
def demo_false():
print("False")
return False
demo_true() and demo_false() # True, False
demo_true() or demo_false() # True
demo_false() and demo_true() # False
demo_false() or demo_true() # False, True
4 Membership Operator¶
The membership operator in
and not in
are used to find if a value is a member of a sequence. A sequence can be a string, a list, a tuple, or even a dictionary.
5 in [1, 5, 7] # True
key = "hi"
greeting = "hello"
key in "hello" # False
key not in greeting # True
table = {key: greeting, "az": "arizona"}
key in table # True
key not in table # False
5 Identity Operator¶
is
and is not
are used to check if two variables refer to the same object, i.e., if two variables are aliases of the same object. Use ==
to check if two values are equal or not. It is not recommended to use identity operator on literal values.
There are some surprises in these two concepts. In Python, small integer values (from -5 to 256, inclusive) and strings are shared by all references for performance reason. Therefore, variables with the same value refer to the same object, so-called interning. But it is implementation-specific.
Practically, it is safe and simple to remember that only an assignment x = y
or a function/method call create an alias.
x = 3
y = 3
x == y # True, of course
x is y # True, interning
x = 257
y = 257
x is y # False !!! no interning
x = "abc"
y = "abc"
x == y # True
x is y # True, interning
x = [1, 2, 3]
y = [1, 2, 3]
x == y # True
x is y # False !!!
z = x
z is x # True
6 Bitwise Operators¶
Python has one unary and several binary bit operators that act on binary data. Their operands only have 0
s or 1
s.
x = 0b01 # binary data, 1
y = 0b10 # binary data, 2
~x # bitwise NOT or complement. result is -2
x & y # bitwise AND, result: 0
x | y # bitwise OR, result: 3
x ^ y # bitwise XOR, result: 3
x << 2 # left-shift, result: 4
x >> 2 # right-shift, result: 0
7 Assignment Operator¶
Assignment operator =
binds a variable in LHS to the RHS expression. It creates the variable if it is the first time binding for the variable, otherwise, it re-binds it to a different object.
The =
assignment operation is not an expression because it binds a variable to an object, but the operation generates no value, i.e., you cannot use an assignment in a place that requires a value. It is a syntax error to write code like (x = 3) = 5
or if (x = 3)
.
Augmented Assignment¶
It is common to use a variable in an arithmetic or bitwise operation and assign the result back to the variable. Augmented assignment makes it simple to write those operations. It works for all binary arithmetic or bitwise operators. The LHS variable is used as the first operand of the operator.
x = 5
x = x + 3
x = x << 2
# Augmented assignment
x += 3
x <<= 2
The Walrus Operator¶
Python 3.8 (released in 2019) brings a walrus :=
operator that work as an assignment expression. It performs two tasks: assign the RHS expression value to the LHS variable and use the value as its expression value.
It combines two tasks into one operation. It makes code simpler in some cases.
# Before Python 3.8
name = input("Please type your name: ")
if name:
print(name)
else:
print("name is empty")
# Since Python 3.8
if (name := input("Please type your name: ")):
print(name)
else:
print("name is empty")
Operator Precedence¶
Operators have different precedences when they are used together in a single expression. For example, the expression 3 + 5 * 4
evaluates 5 * 4
before add them. Thus the result is 23
, not 32
.
The Python document gives a list of operator precedences. You don't need to remember it - you even don't need to read it. The best practices are:
- break long expression into short expressions with only one or two operators
- use parenthesis to make the precedence explicit.
Using the best practices, 3 + 5 * 4
should be written as 3 + (5 * 4)
.
Conditional Expression¶
Python provides a conditional expression syntax to make it easy to choose a value from two conditions.
For example, you want to set a message to odd
or even
based on oddness of a number. Without conditional expression, it needs a four-line statements. With conditional expression, it is one line.
number = int(input('Pease type an integer: '))
if number % 2:
message = "odd"
else:
message = "even"
print(message)
# conditional expression
message = "odd" if number % 2 else "even"
print(message)
Statement¶
A Python program consists of instructions to be executed by the Python interpreter. Those instructions are called statements.
All expressions are executed by the Python interpreter and generate values. Expressions are statements. But a program needs more than expressions.
The assignment name = expression
is not an expression. It is a statement that bind a variable with the value on the RHS.
There are two types of statements: simple statement and compound statement.
Simple Statements¶
Statements that are short and usually written in one line are simple statements.
Simple statements include
- assignment statement
name = expression
- return statement:
return expression
- import statement:
import module_name
- ...
Compound Statements¶
A compound statement contains multiple statements that usually span multiple lines.
Compound statements are used to control program flow or create new data types like functions and classes.
They are not expressions.
They give the "high level" abstractions that make Python more flexible and expressive. Conditional statements, loop statements, function definition are compound statements.
Why Statements?¶
Typically a Python program consists of one or more statements.
All expressions are simple statements. Python has two types of expressions
- those generate a value: all operators, except the assignment operator
=
, act on their operands and create a value. - those don't generate a value. They handle I/O or change program states. For example:
print()
, assignment.
Expressions that generate values are useless if the result is not used in a statement that stores the value in memory/disk, or sends it over network, or displays it in a terminal.
For example, you can write an expression x + 1
as a valid statement in a Python program. But it is a waste of CPU cycles because its result is discarded. A statement like y = x + 1
is useful because the result can be used later.
Similarly, a function call math.sqrt(x)
is useless by itself. Butprint("Hi")
is useful because it displays the string in a console.
Walrus Operator Syntax¶
Walrus operator :=
is interesting because it highlights the difference between a value-generation expression and a statement. Because :=
generate a value, it is useless if its value is not used. You cannot write it in a single line.
For example, it is an SyntaxError
to write the expression x := 5
in a line. Because the evaluated value 5
is not used. If you only need assignment, use an assignment statement.
The following code shows a valid use.
import math
if (x := math.sqrt(5)) > 2:
print(x)