Lectures: Nguyễn Tuấn Phong, Đào Việt Anh
Labs: Trịnh Ngọc Huỳnh, Phạm Tiến Du
Semester: 2025-2026-1
Institute for AI, VNU-UET
if <condition>:
<expression>
...
if <condition>:
<expression>
<expression>
...
else:
<expression>
<expression>
...
if <condition>:
<expression>
<expression>
...
elif <condition>:
<expression>
<expression>
...
else:
<expression>
<expression>
...
x = float(input("Enter a number for x: "))
y = float(input("Enter a number for y: "))
if x == y:
print("x and y are equal")
if y != 0:
print("therefore, x / y is", x / y)
elif x < y:
print("x is smaller")
else:
print("y is smaller")
print("thanks!")
❓Question: Can we use spaces instead of tabs for indentation?
x = float(input("Enter a number for x: "))
y = float(input("Enter a number for y: "))
if x == y:
print("x and y are equal")
if y != 0:
print("therefore, x / y is", x / y)
elif x < y:
print("x is smaller")
else:
print("y is smaller")
print("thanks!")
What if using x = y in Line #4?
→ Get SyntaxError
while <condition>:
<expression>
<expression>
...
Question: What does this program do?
password = ""
while password != "python":
password = input("Enter the password: ")
print("Access granted!")
for <variable> in range(<some_num>):
<expression>
<expression>
...
Question: What does this program do?
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print("I like", fruit)
Iterate through numbers in a sequence:
n = 0
while n < 5:
print(n)
n = n + 1
for n in range(5):
print(n)
mysum = 0
for i in range(7, 10):
mysum += i
print(mysum)
mysum = 0
for i in range(5, 11, 2):
mysum += i
print(mysum)
Question: What happens in the following code?
while <condition_1>:
while <condition_2>:
<expression_a>
break
<expression_b>
<expression_c>
Question: What happens in this program?
mysum = 0
for i in range(5, 11, 2):
mysum += i
if mysum == 5:
break
mysum += 1
print(mysum)
for i in range(5):
if i == 2:
continue
print(i)
| for loops | while loops | |
|---|---|---|
| Iterations | known number of iterations | unbounded number of iterations |
| Early exit | can end early via break | can end early via break |
| Skipping | can skip to next iteration via continue | can skip to next iteration via continue |
| Counters | uses a counter | can use a counter, but must initialize before loop and increment inside loop |
| Rewriting | can rewrite a for loop using a while loop | may not be able to rewrite a while loop using a for loop |
>>> s = "abc"
>>> len(s)
3
s = "abc"
# indexes: 0 1 2
# indexes: -3 -2 -1
s[0] # "a"
s[1] # "b"
s[2] # "c"
s[3] # error (out of bounds)
s[-1] # "c"
s[-2] # "b"
s[-3] # "a"
s = "abcdefgh"
s[3:6] # "def", same as s[3:6:1]
s[3:6:2] # "df"
s[::] # "abcdefgh", same as s[0:len(s):1]
s[::-1] # "hgfedcba", same as s[-1:-(len(s)+1):-1]
s[4:1:-2] # "ec"
>>> s = "hello"
>>> s[0] = 'y'
...
TypeError: 'str' object does not support item assignment
>>> s = 'y' + s[1:len(s)]
>>> s
'yello'
s = "abcdefgh"
for index in range(len(s)):
if s[index] == 'i' or s[index] == 'u':
print("There is an i or u")
for char in s:
if char == 'i' or char == 'u':
print("There is an i or u")
te = () # empty tuple
t = (2, "uet", 3) # tuple with 3 elements
t[0] # 2 # first element
(2, "uet", 3) + (5, 6) # (2, "uet", 3, 5, 6)
t[1:2] # ("uet",) # extra comma → tuple with one element
t[1:3] # ("uet", 3)
len(t) # 3
t[1] = 4 # ❌ error, cannot modify tuple elements
❌ Incorrect
x = y
y = x
✅ Temp var
temp = x
x = y
y = temp
✅ Pythonic swap
(x, y) = (y, x)
a_list = [] # empty list
L = [2, 'a', 4, [1, 2]]
len(L) # 4
L[0] # 2
L[2] + 1 # 5
L[3] # [1, 2], another list!
L[4] # ❌ error (index out of range)
i = 2
L[i-1] # 'a' since L[1] = 'a'
>>> L = [2, 1, 3]
>>> L[1] = 5
>>> L
[2, 5, 3]
→ It’s the same object L, only modified in place.
total = 0
for i in range(len(L)):
total += L[i]
print(total)
total = 0
for x in L:
total += x
print(total)
>>> L = [2, 1, 3]
>>> L.append(5)
>>> L
[2, 1, 3, 5]
L1 = [2, 1, 3]
L2 = [4, 5, 6]
L3 = L1 + L2 # L3 == [2, 1, 3, 4, 5, 6]; L1, L2 unchanged
L1 = [2, 1, 3]
L1.extend([0, 6]) # L1 == [2, 1, 3, 0, 6] (mutated)
L = [2, 1, 3, 6, 3, 7, 0]
L.remove(2) # L == [1, 3, 6, 3, 7, 0]
L.remove(3) # L == [1, 6, 3, 7, 0]
del L[1] # L == [1, 3, 7, 0]
L.pop() # returns 0, L == [1, 3, 7]
>>> s = "I<3 cs"
>>> list(s)
['I', '<', '3', ' ', 'c', 's']
>>> s.split('<')
['I', '3 cs']
>>> L = ['a', 'b', 'cde']
>>> ''.join(L)
'abcde'
>>> '_'.join(L)
'a_b_cde'
L = [9, 6, 0, 3]
sorted(L) # [0, 3, 6, 9], L unchanged
L.sort() # L == [0, 3, 6, 9]
L.reverse() # L == [9, 6, 3, 0]
→ Check Official Python Tutorial for many more!
>>> a = 1
>>> b = a
>>> warm = ['red', 'yellow', 'orange']
>>> hot = warm
>>> hot.append('pink')
>>> print(warm)
['red', 'yellow', 'orange', 'pink']
>>> cool = ['blue', 'green', 'grey']
>>> chill = cool[:] # clone
>>> chill.append('black')
>>> print(chill)
['blue', 'green', 'grey', 'black']
>>> print(cool)
['blue', 'green', 'grey']
>>> warm = ['red', 'yellow', 'orange']
>>> sortedwarm = warm.sort()
>>> print(warm)
['orange', 'red', 'yellow']
>>> print(sortedwarm)
None
>>> cool = ['grey', 'green', 'blue']
>>> sortedcool = sorted(cool)
>>> print(cool)
['grey', 'green', 'blue']
>>> print(sortedcool)
['blue', 'green', 'grey']
>>> warm = ['yellow', 'orange']
>>> hot = ['red']
>>> brightcolors = [warm]
>>> brightcolors.append(hot)
>>> print(brightcolors)
[['yellow', 'orange'], ['red']]
>>> hot.append('pink')
>>> print(hot)
['red', 'pink']
>>> print(brightcolors)
[['yellow', 'orange'], ['red', 'pink']]
⚠️ Avoid mutating a list while iterating over it!
Question: Removing all elements from one list (L1) that are present in another list (L2). Which code is correct?
Code #1
def remove_dups(L1, L2):
for e in L1:
if e in L2:
L1.remove(e)
Code #2
def remove_dups(L1, L2):
L1_copy = L1[:]
for e in L1_copy:
if e in L2:
L1.remove(e)
>>> numbers = {1, 2, 3, 4, 1, 5}
>>> print(numbers)
{1, 2, 3, 4, 5}
>>> numbers[0]
TypeError: 'set' object is not subscriptable
>>> var_a = {}
>>> type(var_a)
<class 'dict'>
>>> var_b = set()
>>> type(var_b)
<class 'set'>
>>> numbers.add(6)
>>> numbers
{1, 2, 3, 4, 5, 6}
>>> numbers = {1, 2, "hello", 4}
>>> numbers
{1, 2, 4, 'hello'}
>>> empty_set = {[1, 2, 4]}
TypeError: unhashable type: 'list'
>>> set([1, 1, 2, 3])
{1, 2, 3}
names = ['Phong', 'Việt Anh', 'Huỳnh', 'Du']
grade = [3.5, 3.8, 3.2, 3.9]
course = ['DSE2049', 'AI3054', 'AI3056', 'DSE3154']
def get_grade(student, name_list, grade_list, course_list):
i = name_list.index(student)
grade = grade_list[i]
course = course_list[i]
return (course, grade)
A list
| Index | Element |
|---|---|
| 0 | Elem 1 |
| 1 | Elem 2 |
| 2 | Elem 3 |
| 3 | Elem 4 |
A dictionary
| Key | Value |
|---|---|
| Key 1 | Val 1 |
| Key 2 | Val 2 |
| Key 3 | Val 3 |
| Key 4 | Val 4 |
# empty dict
my_dict = {}
# a simple grade book
grades = {
'Phong': 3.5,
'Việt Anh': 3.8,
'Huỳnh': 3.2,
'Du': 3.9
}
| Key | Value |
|---|---|
| 'Phong' | 3.5 |
| 'Việt Anh' | 3.8 |
| 'Huỳnh' | 3.2 |
| 'Du' | 3.9 |
>>> grades = {'Phong': 3.5, 'Việt Anh': 3.8, 'Huỳnh': 3.2, 'Du': 3.9}
>>> grades['Phong']
3.5
>>> grades['An']
KeyError: 'An'
>>> grades = {'Phong': 3.5, 'Việt Anh': 3.8, 'Huỳnh': 3.2, 'Du': 3.9}
Add an entry
>>> grades['An'] = 4.0
Test if a key is in the dictionary
>>> 'Phong' in grades
True
>>> 'Long' in grades
False
Delete an entry
>>> del(grades['Du'])
>>> grades = {'Phong': 3.5, 'Việt Anh': 3.8, 'Huỳnh': 3.2, 'Du': 3.9}
Iterate over keys
>>> grades.keys()
dict_keys(['Phong', 'Việt Anh', 'Huỳnh', 'Du'])
Iterate over values
>>> grades.values()
dict_values([3.5, 3.8, 3.2, 3.9])
🆕 Python3.7+: Iteration order matches insertion order
| Aspect | list | dict |
|---|---|---|
| Structure | ordered sequence of elements | matches “keys” to “values” |
| Lookup | Look up elements by an integer index | Look up one item by another item |
| Order | Indices have an order | Python 3.7+: insertion order preserved |
| Index/Key | Index is an integer | Key can be any immutable type |