Bài 1.14. Bài tập Python: tính toán đơn giản, list + dict

Chào mừng các bạn đến với bài học tiếp theo trong chuỗi bài về Python cơ bản! Hôm nay, chúng ta sẽ đi sâu vào ba khía cạnh cực kỳ quan trọng và thường xuyên được sử dụng trong lập trình Python: thực hiện các phép toán đơn giản, làm việc với danh sách (list)từ điển (dict). Đây là những viên gạch nền tảng giúp bạn xây dựng nên những chương trình phức tạp hơn sau này. Hãy cùng bắt đầu khám phá nhé!

1. Tính toán đơn giản trong Python

Python không chỉ là một ngôn ngữ lập trình mạnh mẽ mà còn có thể được sử dụng như một chiếc máy tính cầm tay siêu hạng. Bạn có thể thực hiện hầu hết các phép toán cơ bản một cách dễ dàng.

Các toán tử số học cơ bản
  • + : Phép cộng
  • - : Phép trừ
  • * : Phép nhân
  • / : Phép chia (luôn trả về số thực - float)
  • % : Phép chia lấy dư (modulo)
  • // : Phép chia lấy phần nguyên (floor division)
  • ``** : Phép lũy thừa

Hãy xem qua một vài ví dụ:

# Khai báo hai biến số
a = 15
b = 4

# Thực hiện các phép toán
tong = a + b
hieu = a - b
tich = a * b
thuong = a / b  # Kết quả sẽ là số thực
chia_lay_du = a % b
chia_lay_nguyen = a // b
luy_thua = a ** 2 # 15 mũ 2

# In kết quả ra màn hình
print(f"Tổng của {a}{b} là: {tong}") # Output: Tổng của 15 và 4 là: 19
print(f"Hiệu của {a}{b} là: {hieu}") # Output: Hiệu của 15 và 4 là: 11
print(f"Tích của {a}{b} là: {tich}") # Output: Tích của 15 và 4 là: 60
print(f"Thương của {a}{b} là: {thuong}") # Output: Thương của 15 và 4 là: 3.75
print(f"{a} chia {b} lấy dư: {chia_lay_du}") # Output: 15 chia 4 lấy dư: 3
print(f"{a} chia {b} lấy phần nguyên: {chia_lay_nguyen}") # Output: 15 chia 4 lấy phần nguyên: 3
print(f"{a} mũ 2 là: {luy_thua}") # Output: 15 mũ 2 là: 225

# Bạn cũng có thể thực hiện phép toán trực tiếp
print(f"Kết quả của (5 + 3) * 2 là: {(5 + 3) * 2}") # Output: Kết quả của (5 + 3) * 2 là: 16

Giải thích code: Trong đoạn code trên, chúng ta khai báo hai biến ab. Sau đó, chúng ta lần lượt thực hiện các phép toán cộng, trừ, nhân, chia, chia lấy dư, chia lấy nguyên và lũy thừa với hai biến này, lưu kết quả vào các biến tương ứng. Cuối cùng, chúng ta sử dụng hàm print() kết hợp với f-string để hiển thị kết quả một cách rõ ràng. Lưu ý rằng phép chia / luôn trả về kiểu float, trong khi // trả về phần nguyên của phép chia. Thứ tự ưu tiên của các phép toán cũng được tuân thủ (nhân/chia trước, cộng/trừ sau, lũy thừa cao nhất), và bạn có thể dùng dấu ngoặc () để thay đổi thứ tự này.

2. Làm việc với Danh sách (List)

List là một trong những cấu trúc dữ liệu linh hoạtđược sử dụng nhiều nhất trong Python. Nó cho phép bạn lưu trữ một chuỗi các mục (có thể thuộc nhiều kiểu dữ liệu khác nhau) theo một thứ tự nhất định và bạn có thể thay đổi nội dung của nó sau khi tạo.

Khởi tạo List

Bạn có thể tạo list bằng cách đặt các phần tử bên trong cặp dấu ngoặc vuông [], cách nhau bởi dấu phẩy ,.

# List chứa các số nguyên
numbers = [1, 5, 2, 8, 3]
print(f"List số nguyên: {numbers}")

# List chứa các chuỗi
fruits = ["táo", "chuối", "cam"]
print(f"List chuỗi: {fruits}")

# List chứa nhiều kiểu dữ liệu khác nhau
mixed_list = [1, "Python", 3.14, True, None]
print(f"List hỗn hợp: {mixed_list}")

# List rỗng
empty_list = []
print(f"List rỗng: {empty_list}")

# Tạo list từ một chuỗi (mỗi ký tự là một phần tử)
char_list = list("hello")
print(f"List từ chuỗi 'hello': {char_list}") # Output: ['h', 'e', 'l', 'l', 'o']

Giải thích code: Các ví dụ trên minh họa nhiều cách tạo list: chứa cùng kiểu dữ liệu (số nguyên, chuỗi), chứa nhiều kiểu dữ liệu khác nhau, tạo list rỗng, và tạo list từ một đối tượng có thể lặp lại (iterable) như chuỗi bằng hàm list().

Truy cập phần tử trong List

Bạn có thể truy cập các phần tử trong list bằng chỉ số (index). Chỉ số trong Python bắt đầu từ 0 cho phần tử đầu tiên. Bạn cũng có thể dùng chỉ số âm để truy cập từ cuối list (-1 là phần tử cuối cùng).

my_list = ["a", "b", "c", "d", "e"]

# Truy cập phần tử đầu tiên (chỉ số 0)
print(f"Phần tử đầu tiên: {my_list[0]}") # Output: a

# Truy cập phần tử thứ ba (chỉ số 2)
print(f"Phần tử thứ ba: {my_list[2]}") # Output: c

# Truy cập phần tử cuối cùng (chỉ số -1)
print(f"Phần tử cuối cùng: {my_list[-1]}") # Output: e

# Truy cập phần tử kế cuối (chỉ số -2)
print(f"Phần tử kế cuối: {my_list[-2]}") # Output: d

Giải thích code: Chúng ta sử dụng cú pháp tên_list[chỉ_số] để lấy giá trị của phần tử tại vị trí mong muốn. Chỉ số dương đếm từ đầu list (bắt đầu từ 0), chỉ số âm đếm từ cuối list (bắt đầu từ -1).

Cắt List (Slicing)

Slicing cho phép bạn lấy ra một phần của list, tạo thành một list con mới. Cú pháp là tên_list[start:stop:step].

  • start: chỉ số bắt đầu (bao gồm). Mặc định là 0.
  • stop: chỉ số kết thúc (không bao gồm). Mặc định là hết list.
  • step: bước nhảy. Mặc định là 1.
my_list = ["a", "b", "c", "d", "e", "f", "g"]

# Lấy các phần tử từ chỉ số 1 đến chỉ số 3 (không bao gồm 4)
sub_list1 = my_list[1:4]
print(f"List con từ index 1 đến 3: {sub_list1}") # Output: ['b', 'c', 'd']

# Lấy các phần tử từ đầu đến chỉ số 2 (không bao gồm 3)
sub_list2 = my_list[:3]
print(f"List con từ đầu đến index 2: {sub_list2}") # Output: ['a', 'b', 'c']

# Lấy các phần tử từ chỉ số 3 đến hết list
sub_list3 = my_list[3:]
print(f"List con từ index 3 đến cuối: {sub_list3}") # Output: ['d', 'e', 'f', 'g']

# Lấy toàn bộ list (tạo bản sao nông)
sub_list4 = my_list[:]
print(f"Bản sao của list: {sub_list4}") # Output: ['a', 'b', 'c', 'd', 'e', 'f', 'g']

# Lấy các phần tử với bước nhảy là 2
sub_list5 = my_list[::2]
print(f"List con với bước nhảy 2: {sub_list5}") # Output: ['a', 'c', 'e', 'g']

# Đảo ngược list bằng slicing
reversed_list = my_list[::-1]
print(f"List đảo ngược: {reversed_list}") # Output: ['g', 'f', 'e', 'd', 'c', 'b', 'a']

Giải thích code: Các ví dụ slicing cho thấy sự linh hoạt trong việc trích xuất dữ liệu từ list. Bạn có thể lấy một đoạn liên tục, lấy từ đầu/cuối, sao chép toàn bộ list, hoặc lấy các phần tử cách quãng. Slicing luôn tạo ra một list mới, không làm thay đổi list gốc.

Thay đổi phần tử trong List

List là mutable (có thể thay đổi), nghĩa là bạn có thể thay đổi giá trị các phần tử, thêm hoặc xóa phần tử.

my_list = [10, 20, 30, 40, 50]
print(f"List ban đầu: {my_list}")

# Thay đổi giá trị phần tử tại chỉ số 1
my_list[1] = 25
print(f"Sau khi thay đổi phần tử thứ hai: {my_list}") # Output: [10, 25, 30, 40, 50]

# Thêm phần tử vào cuối list bằng append()
my_list.append(60)
print(f"Sau khi thêm 60 vào cuối: {my_list}") # Output: [10, 25, 30, 40, 50, 60]

# Chèn phần tử vào vị trí cụ thể bằng insert()
my_list.insert(2, 28) # Chèn 28 vào chỉ số 2
print(f"Sau khi chèn 28 vào index 2: {my_list}") # Output: [10, 25, 28, 30, 40, 50, 60]

# Xóa phần tử đầu tiên có giá trị là 30 bằng remove()
my_list.remove(30)
print(f"Sau khi xóa giá trị 30: {my_list}") # Output: [10, 25, 28, 40, 50, 60]

# Xóa phần tử tại chỉ số cụ thể bằng pop()
# pop() trả về giá trị đã xóa
removed_item = my_list.pop(3) # Xóa phần tử tại chỉ số 3 (là số 40)
print(f"Phần tử đã xóa bằng pop(3): {removed_item}") # Output: 40
print(f"List sau khi pop(3): {my_list}") # Output: [10, 25, 28, 50, 60]

# Xóa phần tử cuối cùng bằng pop() không có đối số
last_item = my_list.pop()
print(f"Phần tử cuối đã xóa bằng pop(): {last_item}") # Output: 60
print(f"List sau khi pop(): {my_list}") # Output: [10, 25, 28, 50]

# Xóa phần tử bằng từ khóa del
del my_list[0] # Xóa phần tử đầu tiên
print(f"List sau khi del my_list[0]: {my_list}") # Output: [25, 28, 50]

Giải thích code: Ví dụ này minh họa các cách phổ biến để thay đổi list:

  • Gán giá trị mới cho một phần tử qua chỉ số (my_list[1] = 25).
  • append(item): Thêm item vào cuối list.
  • insert(index, item): Chèn item vào vị trí index. Các phần tử sau đó sẽ dịch sang phải.
  • remove(value): Xóa lần xuất hiện đầu tiên của value trong list. Gây lỗi nếu value không tồn tại.
  • pop(index): Xóa và trả về phần tử tại index. Nếu không có index, xóa và trả về phần tử cuối cùng.
  • del tên_list[index]: Xóa phần tử tại index. Cũng có thể dùng để xóa một slice (del my_list[1:3]).
Một số phương thức List hữu ích khác
  • len(list): Trả về số lượng phần tử trong list.
  • list.sort(): Sắp xếp các phần tử trong list (thay đổi list gốc). Lưu ý: các phần tử phải cùng kiểu có thể so sánh được.
  • list.reverse(): Đảo ngược thứ tự các phần tử trong list (thay đổi list gốc).
  • list.count(value): Đếm số lần xuất hiện của value trong list.
  • list.index(value): Trả về chỉ số của lần xuất hiện đầu tiên của value. Gây lỗi nếu value không có.
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print(f"List số: {numbers}")

# Độ dài list
print(f"Độ dài list: {len(numbers)}") # Output: 8

# Đếm số lần xuất hiện của số 1
print(f"Số lần xuất hiện của 1: {numbers.count(1)}") # Output: 2

# Tìm chỉ số đầu tiên của số 5
print(f"Chỉ số của số 5: {numbers.index(5)}") # Output: 4

# Sắp xếp list tăng dần (thay đổi list gốc)
numbers.sort()
print(f"List sau khi sắp xếp tăng dần: {numbers}") # Output: [1, 1, 2, 3, 4, 5, 6, 9]

# Đảo ngược list (thay đổi list gốc)
numbers.reverse()
print(f"List sau khi đảo ngược: {numbers}") # Output: [9, 6, 5, 4, 3, 2, 1, 1]

3. Làm việc với Từ điển (Dictionary - Dict)

Dictionary là một cấu trúc dữ liệu dùng để lưu trữ dữ liệu dưới dạng các cặp key: value (khóa: giá trị). Mỗi key trong dictionary phải là duy nhất và thường là chuỗi hoặc số (nói chung là các kiểu dữ liệu không thể thay đổi - immutable). Value có thể là bất kỳ kiểu dữ liệu nào, kể cả list hoặc một dictionary khác.

Trong các phiên bản Python gần đây (3.7+), dictionary duy trì thứ tự chèn các phần tử.

Khởi tạo Dictionary

Bạn có thể tạo dictionary bằng cách đặt các cặp key: value bên trong cặp dấu ngoặc nhọn {}, cách nhau bởi dấu phẩy ,.

# Dictionary thông tin sinh viên
student = {
    "name": "Bình",
    "age": 21,
    "major": "Công nghệ thông tin",
    "gpa": 3.5
}
print(f"Thông tin sinh viên: {student}")

# Dictionary rỗng
empty_dict = {}
print(f"Dictionary rỗng: {empty_dict}")

# Tạo dictionary bằng hàm dict()
car = dict(brand="Toyota", model="Camry", year=2022)
print(f"Thông tin xe: {car}")

Giải thích code: Ví dụ đầu tiên tạo một dictionary student với các key là chuỗi ("name", "age", "major", "gpa") và các value tương ứng. Ví dụ thứ hai tạo một dictionary rỗng. Ví dụ thứ ba sử dụng hàm dict() với các đối số keyword để tạo dictionary car.

Truy cập giá trị trong Dictionary

Bạn có thể truy cập giá trị (value) thông qua khóa (key) tương ứng bằng cách sử dụng dấu ngoặc vuông [] hoặc phương thức get().

student = {
    "name": "Bình",
    "age": 21,
    "major": "Công nghệ thông tin"
}

# Truy cập bằng key dùng []
student_name = student["name"]
print(f"Tên sinh viên: {student_name}") # Output: Bình

# Truy cập bằng phương thức get()
student_age = student.get("age")
print(f"Tuổi sinh viên: {student_age}") # Output: 21

# Sự khác biệt khi key không tồn tại:
# Dùng [] sẽ gây lỗi KeyError
try:
    student_gpa = student["gpa"]
except KeyError:
    print("Lỗi: Key 'gpa' không tồn tại trong dictionary!")

# Dùng get() sẽ trả về None (mặc định) hoặc giá trị bạn cung cấp
student_gpa = student.get("gpa")
print(f"GPA sinh viên (get, mặc định): {student_gpa}") # Output: None

student_gpa_default = student.get("gpa", "Chưa có điểm")
print(f"GPA sinh viên (get, có giá trị mặc định): {student_gpa_default}") # Output: Chưa có điểm

Giải thích code: Chúng ta có thể lấy giá trị bằng cách tên_dict['key']. Tuy nhiên, nếu key không tồn tại, chương trình sẽ báo lỗi KeyError. Phương thức tên_dict.get('key', default_value) an toàn hơn. Nếu key tồn tại, nó trả về giá trị tương ứng. Nếu không, nó trả về None (nếu default_value không được cung cấp) hoặc trả về chính default_value mà bạn đã chỉ định.

Thay đổi Dictionary

Dictionary là mutable, bạn có thể thêm cặp key-value mới, cập nhật giá trị của key đã có, hoặc xóa cặp key-value.

student = {
    "name": "Bình",
    "age": 21,
    "major": "Công nghệ thông tin"
}
print(f"Dictionary ban đầu: {student}")

# Cập nhật giá trị của key đã có
student["age"] = 22
print(f"Sau khi cập nhật tuổi: {student}") # Output: {'name': 'Bình', 'age': 22, 'major': 'Công nghệ thông tin'}

# Thêm cặp key-value mới
student["gpa"] = 3.6
student["university"] = "Đại học Bách Khoa"
print(f"Sau khi thêm GPA và trường: {student}") # Output: {'name': 'Bình', 'age': 22, 'major': 'Công nghệ thông tin', 'gpa': 3.6, 'university': 'Đại học Bách Khoa'}

# Xóa cặp key-value bằng pop()
# pop() xóa key và trả về value tương ứng
major = student.pop("major")
print(f"Ngành đã xóa: {major}") # Output: Công nghệ thông tin
print(f"Sau khi xóa major: {student}") # Output: {'name': 'Bình', 'age': 22, 'gpa': 3.6, 'university': 'Đại học Bách Khoa'}

# Xóa cặp key-value bằng từ khóa del
del student["age"]
print(f"Sau khi xóa age bằng del: {student}") # Output: {'name': 'Bình', 'gpa': 3.6, 'university': 'Đại học Bách Khoa'}

# Cập nhật nhiều cặp key-value bằng update()
# update() có thể dùng để thêm mới hoặc cập nhật key đã có
student.update({"gpa": 3.7, "city": "Hà Nội"})
print(f"Sau khi update GPA và thêm city: {student}") # Output: {'name': 'Bình', 'gpa': 3.7, 'university': 'Đại học Bách Khoa', 'city': 'Hà Nội'}

Giải thích code:

  • Để thêm mới hoặc cập nhật một cặp key-value, bạn chỉ cần gán giá trị: tên_dict[key] = value. Nếu key đã tồn tại, giá trị cũ sẽ bị ghi đè. Nếu key chưa tồn tại, cặp key-value mới sẽ được thêm vào.
  • pop(key): Xóa cặp có key chỉ định và trả về value của nó. Gây lỗi nếu key không tồn tại.
  • del tên_dict[key]: Xóa cặp có key chỉ định. Gây lỗi nếu key không tồn tại.
  • update(other_dict): Cập nhật dictionary hiện tại với các cặp key-value từ other_dict. Các key trùng lặp sẽ bị ghi đè bởi giá trị trong other_dict.
Một số phương thức Dictionary hữu ích khác
  • len(dict): Trả về số lượng cặp key-value.
  • dict.keys(): Trả về một đối tượng view chứa tất cả các key.
  • dict.values(): Trả về một đối tượng view chứa tất cả các value.
  • dict.items(): Trả về một đối tượng view chứa các cặp (key, value).

Các đối tượng view này sẽ phản ánh những thay đổi trong dictionary gốc.

student = {
    "name": "Chi",
    "age": 20,
    "major": "Kinh tế",
    "gpa": 3.8
}

# Lấy số lượng cặp key-value
print(f"Số lượng thông tin: {len(student)}") # Output: 4

# Lấy danh sách các key
keys = student.keys()
print(f"Các khóa (keys): {keys}") # Output: dict_keys(['name', 'age', 'major', 'gpa'])
print(f"Kiểu dữ liệu của keys: {type(keys)}") # Output: <class 'dict_keys'>

# Lấy danh sách các value
values = student.values()
print(f"Các giá trị (values): {values}") # Output: dict_values(['Chi', 20, 'Kinh tế', 3.8])
print(f"Kiểu dữ liệu của values: {type(values)}") # Output: <class 'dict_values'>

# Lấy danh sách các cặp (key, value)
items = student.items()
print(f"Các cặp (key, value): {items}") # Output: dict_items([('name', 'Chi'), ('age', 20), ('major', 'Kinh tế'), ('gpa', 3.8)])
print(f"Kiểu dữ liệu của items: {type(items)}") # Output: <class 'dict_items'>

# Có thể chuyển đổi các view này thành list nếu cần
key_list = list(student.keys())
print(f"Danh sách các key (dạng list): {key_list}") # Output: ['name', 'age', 'major', 'gpa']
Duyệt qua Dictionary

Bạn có thể dùng vòng lặp for để duyệt qua các key, value hoặc cả hai.

student = {
    "name": "Dũng",
    "age": 22,
    "major": "Cơ khí"
}

print("\nDuyệt qua các keys:")
# Cách 1: Mặc định duyệt qua keys
for key in student:
    print(f"Key: {key}, Value: {student[key]}")
# Cách 2: Dùng keys() rõ ràng
# for key in student.keys():
#     print(f"Key: {key}")

print("\nDuyệt qua các values:")
for value in student.values():
    print(f"Value: {value}")

print("\nDuyệt qua các cặp (key, value):")
for key, value in student.items():
    print(f"Key: {key} -> Value: {value}")

Giải thích code:

  • Khi bạn lặp trực tiếp for key in student, bạn sẽ duyệt qua các key của dictionary.
  • Để duyệt qua các value, bạn cần dùng student.values().
  • Để duyệt qua cả keyvalue cùng lúc một cách hiệu quả, hãy dùng student.items(). Vòng lặp sẽ trả về một tuple (key, value) trong mỗi lần lặp, bạn có thể giải nén (unpack) nó thành hai biến riêng biệt như key, value.

Qua bài học này, bạn đã nắm vững cách thực hiện các phép toán số học cơ bản, cũng như cách tạo, truy cập, thay đổi và duyệt qua hai cấu trúc dữ liệu cực kỳ quan trọng là ListDictionary trong Python. Hãy thực hành thật nhiều với các ví dụ và thử tự tạo ra các bài toán nhỏ để vận dụng kiến thức vừa học nhé!

Comments

There are no comments at the moment.