Bài F11. Danh sách

Nội dung lý thuyết

1. Danh sách trong Python

  • Trong Python, danh sách là một dãy các phần tử có thể có kiểu dữ liệu bất kỳ và được khởi tạo bằng cú pháp:

<tên danh sách> = [<phần tử 0>, <phần tử 1>, ..., <phần tử n>]
  • Các phần tử có thể có kiểu dữ liệu giống hoặc khác nhau: số nguyên, số thực, chuỗi, giá trị logic (True/False), None, danh sách con,...

  • Có thể truy cập từng phần tử của danh sách thông qua chỉ số. Để truy cập phần tử có chỉ số i dùng cú pháp: A[i].

Ví dụ 1:

A = [1, 3, 4, 2]
A[0]     # phần tử đầu tiên là 1
A[3]     # phần tử có chỉ số 3 là 2
A[-1]    # phần tử cuối cùng là 2

B = [1, 2, "Tin học 10", "Python", True, None]
B[2]     # "Tin học 10"
B[-2]    # True
  • Trong Python, chỉ số của các phần tử có thể được đánh bằng chỉ số dương (từ trái sang phải, bắt đầu từ 0) hoặc chỉ số âm (từ phải sang trái, bắt đầu từ -1).

 Danh sách A = [2,6,5,1,3] với chỉ số dương và âm

  • Việc chỉ số hóa từng phần tử giúp danh sách hoạt động như mảng trong ngôn ngữ lập trình khác, nhưng trong Python, các phần tử không bắt buộc phải cùng kiểu dữ liệu.

  • Chiều dài của danh sách là số phần tử trong danh sách.

    • Danh sách rỗng là danh sách không có phần tử nào, có chiều dài bằng 0 và được ký hiệu là [].

    • Sử dụng hàm len(A) để lấy chiều dài danh sách.

  • Nếu danh sách chứa phần tử là một danh sách khác thì gọi là danh sách lồng.

    • Khi danh sách A có phần tử là danh sách con, thì A[i][j] dùng để truy cập phần tử thứ j trong danh sách con A[i].

    • Dùng lệnh type() để kiểm tra kiểu dữ liệu của các phần tử.

Ví dụ 2:

A = [3, [5, 6, 7], True]
A[1]       # [5, 6, 7]
A[1][1]    # 6
type(A[1])     # <class 'list'>
type(A[1][1])  # <class 'int'>

Danh sách A = [3, [5,6,7], True] và truy cập danh sách con

2. Một số phép toán về danh sách

a) Phép duyệt danh sách

  • Dùng lệnh for để duyệt từng phần tử trong danh sách.

  • Có 2 dạng lệnh:

    • for <biến> in range(<n>):

    • for <biến> in <danh sách>:

Ví dụ 3: Chương trình sau hiển thị các phần tử của danh sách A.

A = [1, 6, 2]
for i in range(len(A)):
    print(A[i], end = ' ')
# Output: 1 6 2

for i in A:
    print(i, end = ' ')
# Output: 1 6 2

b) Phép tìm kiếm trong danh sách

  • Dùng toán tử in để kiểm tra phần tử có nằm trong danh sách hay không.

  • Dùng toán tử not in để kiểm tra phần tử không nằm trong danh sách.

Cú pháp:

<phần tử> in <danh sách>
<phần tử> not in <danh sách>
  • Trả về True nếu tìm thấy phần tử, ngược lại trả về False.

Ví dụ 4: Các lệnh minh họa phép tìm kiếm phần tử trong danh sách.

A = [1, [2, 3], 4]
2 in A         # False
B = [2, 3]
B in A         # True
4 not in A     # False

c) Phép kết nối danh sách

  • Dùng toán tử + để kết nối hai hoặc nhiều danh sách lại thành một.

Cú pháp:

​<danh sách 1> + <danh sách 2> + ... + <danh sách n>

Ví dụ 5: Cách lệnh kết nối hai danh sách A và B gán cho danh sách C.

A = [1, 6, 2]
B = [4, 5]
C = A + B
print(C)    # [1, 6, 2, 4, 5]

d) Phép nhân bản danh sách

  • Dùng toán tử * để nhân bản danh sách nhiều lần.

Cú pháp:

<danh sách gốc> * <số lần>
  • Nếu số lần là số âm hoặc bằng 0 → danh sách mới là danh sách rỗng.

Ví dụ 6: Các lệnh dưới minh họa nhân bản danh sách.

A = [1, 6, 2]
B = A * 2       # [1, 6, 2, 1, 6, 2]
C = A * -1      # []
D = [0] * 3     # [0, 0, 0]

3. Gán các phần tử của danh sách cho các biến

  • Có thể gán lần lượt các phần tử của danh sách cho các biến bằng cú pháp:

<tên biến 1>, <tên biến 2>, ..., <tên biến n> = <danh sách có độ dài n>
  • Số lượng biến phải bằng đúng số phần tử trong danh sách.

Ví dụ 7: Trong các lệnh sau đây, các phần tử của danh sách A được gán lần lượt cho các biến b, c, d và các phần tử của danh sách [5,"An"] được án cho hai biến e, f.

A = [1, [2, 3], 4]
b, c, d = A
e,f = [5,"An"]
print (b,c,d,e,f,sep=";")
1; [2, 3];4;5;An

4. Tạo danh sách

  • Có thể tạo danh sách bằng vòng lặp for – range():

Ví dụ:

A = [0 for i in range(3)]       # [0, 0, 0]
B = [2*i for i in range(0, 3)]  # [0, 2, 4]
C = [[i, 2*i, 0] for i in range(0, 5, 2)]
# C = [[0, 0, 0], [2, 4, 0], [4, 8, 0]]

 Gán danh sách A cho danh sách B

  • Khi gán B = A, cả hai danh sách cùng dùng chung 1 vùng nhớ. Mọi thay đổi ở danh sách A cũng làm thay đổi B và ngược lại.

Ví dụ 8: Gán A cho B và thay đổi A làm thay đổi B

A = [1, 6, 2]
B = A
A[0] = 5
print(A)   # [5, 6, 2]
print(B)   # [5, 6, 2]

Gán danh sách mới tách biệt

  • Nếu sau khi gán A cho B, tiếp tục gán B = <danh sách mới>, thì lúc này vùng nhớ của B tách khỏi A.

Ví dụ 9: Gán danh sách mới cho B nên B tách khỏi A

A = [1, 6, 2]
B = A
B = [4, 7]
A[0] = 5
print(A)   # [5, 7]
print(B)   # [1, 6, 2]

Tạo bản sao danh sách A bằng cách gán từng phần tử

Gồm 2 bước:

  1. Tạo danh sách B gồm các phần tử None, số phần tử bằng với A.

  2. Gán từng phần tử từ A cho B.

Ví dụ 10: Gán từng phần tử A vào B để tạo bản sao độc lập

A = [1, 6, 2]
B = [None]*len(A)
for i in range(len(A)):
    B[i] = A[i]

A[0] = 5
print(A)   # [5, 6, 2]
print(B)   # [1, 6, 2]