Kiểu danh sách (list)
Dữ liệu kiểu list trong lập trình Python là một kiểu dữ liệu được sử dụng phổ biến. Chúng ta sẽ đi nghiên cứu chi tiết về cách sử dụng nó.
Cấu trúc tuần tự (sequence) trong Python là một số cấu trúc dữ liệu đặc biệt. Đặc thù của loại cấu trúc này là chứa nhiều phần tử, và mỗi phần tử được đánh số thứ tự để dễ truy xuất. Các loại cấu trúc này cũng có chung nhiều phép toán xử lý (như đánh chỉ số, cắt lát, ghép, lặp, v.v.).
Danh sách (list) là một trong những kiểu dữ liệu tuần tự được sử dụng phổ biến nhất của Python. Các kiểu tuần tự thường gặp khác là tuple và dict.
Sau đây chúng ta sẽ đi xem xét chi tiết về cách sử dụng dữ liệu kiểu list trong Python qua các ví dụ cụ thể.
Ví dụ về danh sách (list) trong Python
Xem xét một ví dụ về danh sách (list) như sau:
Ví dụ
>>> # lập danh sách ngôn ngữ lập trình phổ biến nhất
>>> languages = ['Python', 'Java', 'C/C++', 'Javascript', 'Go', 'R', 'Swift', 'PHP', 'C#']
>>> type(languages)
<class 'list'>
>>> # in danh sách và kiểu
>>> languages
['Python', 'Java', 'C/C++', 'Javascript', 'Go', 'R', 'Swift', 'PHP', 'C#']
>>> # duyệt danh sách trong vòng for
>>> for language in languages:
... print(language)
...
Python
Java
C/C++
Javascript
Go
R
Swift
PHP
C#
>>> # lấy ra phần tử đầu tiên
>>> print('The most popular language is', languages[0])
The most popular language is Python
>>> # lấy ra 3 phần tử đầu tiên
>>> print('The top 3 languages are', languages[0:3])
The top 3 languages are ['Python', 'Java', 'C/C++']
>>> # thêm phần tử mới
>>> languages += ['Matlab']
>>> languages
['Python', 'Java', 'C/C++', 'Javascript', 'Go', 'R', 'Swift', 'PHP', 'C#', 'Matlab']
>>> # cập nhật phần tử số 9
>>> languages[9] = 'Perl'
>>> languages
['Python', 'Java', 'C/C++', 'Javascript', 'Go', 'R', 'Swift', 'PHP', 'C#', 'Perl']
>>> # xóa phần tử số 9
>>> del languages[9]
>>> languages
['Python', 'Java', 'C/C++', 'Javascript', 'Go', 'R', 'Swift', 'PHP', 'C#']
>>> # xóa các phần tử từ vị trí số 5 về cuối
>>> del languages[5:]
>>> languages
['Python', 'Java', 'C/C++', 'Javascript', 'Go']
Nếu muốn chạy ở dạng script bạn dùng code sau:
Ví dụ
languages = ['Python', 'Java', 'C/C++', 'Javascript', 'Go', 'R', 'Swift', 'PHP', 'C#']
# in danh sách và kiểu
print(type(languages), languages)
# duyệt danh sách trong vòng for
print('Most popular programming languages:')
for language in languages:
print(language)
# lấy ra phần tử đầu tiên
print('The most popular language is', languages[0])
# lấy ra 3 phần tử đầu tiên
print('The top 3 languages are', languages[0:3])
# thêm phần tử mới
languages += ['Matlab']
print(languages)
# cập nhật phần tử số 9
languages[9] = 'Perl'
print(languages)
# xóa phần tử số 9
del languages[9]
print(languages)
# xóa các phần tử từ vị trí số 5 về cuối
del languages[5:]
print(languages)
Ví dụ trên minh họa cách làm việc cơ bản với kiểu list trong Python.
Kiểu list trong Python
list là một kiểu dữ liệu rất đa năng trong Python có khả năng chứa một danh sách các phần tử (có thể khác kiểu).
Python quy định giá trị kiểu list phải viết trong cặp dấu ngoặc vuông, các phần tử tách nhau bởi dấu phẩy. Các phần tử trong danh sách được đánh chỉ số (index). Chỉ số bắt đầu từ 0 (giống trong C) và theo vị trí xuất hiện của phần tử.
Ví dụ
companies = ['Google', 'Apple', 'Microsoft', 'Facebook']
là lệnh tạo danh sách gồm 4 phần tử và biến companies trỏ tới. Trong đó, ‘Google’ được đánh chỉ số 0, ‘Apple’ được đánh chỉ số 1, v.v.. Cả 4 phần tử này đều thuộc kiểu str (chuỗi).
Danh sách cũng có thể không chứa phần tử nào. Danh sách không chứa phần tử gọi là danh sách rỗng/trống. Danh sách rỗng được biểu diễn bằng []
.
Ví dụ: empty = []
.
Biến kiểu list có thể chứa các phần tử không cùng kiểu. Ví dụ, trong cùng một biến list có thể chứa phần tử kiểu chuỗi (str) và các kiểu số (int, float, complex).
Ví dụ
>>> mixed = ['Google', 'Apple', 'Microsoft', 'Facebook', 1945, 1954, 1975]
>>> mixed
['Google', 'Apple', 'Microsoft', 'Facebook', 1945, 1954, 1975]
Kiểu list trong Python tương tự như List<object>
hoặc ArrayList
trong C#.
Danh sách có thể chứa cả danh sách khác. Khi này nó được gọi là danh sách lồng nhau (nested list).
Ví dụ
>>> matrix = [[1, 2], [3, 4]]
>>> matrix
[[1, 2], [3, 4]]
>>> nested = ['Russia', 'Canada', 'USA', 'China', 'Brazil', [17.09, 9.9, 9.8, 9.5, 8.5]]
>>> nested
['Russia', 'Canada', 'USA', 'China', 'Brazil', [17.09, 9.9, 9.8, 9.5, 8.5]]
Ngoài việc viết trực tiếp các phần tử, bạn có thể tạo danh sách tự động theo cách sau:
Ví dụ
>>> # lập danh sách các số có dạng 2^x với x thuộc [0, 9]
>>> pow2 = [2 ** x for x in range(10)]
>>> pow2
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
>>> # lập danh sách các số lẻ từ 1 đến 20
>>> odds = [x for x in range(20) if x % 2 == 1]
>>> odds
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
>>> # ghép cặp từ hai danh sách
>>> phrases = [x+y for x in ['Python ','C '] for y in ['Language', 'Programming']]
>>> phrases
['Python Language', 'Python Programming', 'C Language', 'C Programming']
Cách tạo danh sách này có tên gọi riêng là list comprehension. Đây là cách tốt nhất để tạo ra các danh sách dữ liệu.
Truy xuất phần tử của list
Phép toán cơ bản nhất của danh sách là truy xuất phần tử. Python cho phép truy xuất từng phần tử hoặc nhóm phần tử thông qua phép toán cắt (slice) hoặc cắt đoạn (range slice).
Hãy xem ví dụ sau:
Ví dụ
>>> countries = ['Russia', 'Canada', 'USA', 'China', 'Brazil', 'Australia']
>>> countries[1]
'Canada'
countries[1] là phép toán slice (cắt) – trích một phần tử trong danh sách countries theo chỉ số. Phép toán này tương tự như phép toán truy cập phần tử của mảng trong ngôn ngữ C. Lưu ý chỉ số trong Python bắt đầu từ 0 (giống như trong C).
Nếu bạn sử dụng chỉ số âm, Python sẽ tính từ cuối danh sách.
Ví dụ
>>> countries = ['Russia', 'Canada', 'USA', 'China', 'Brazil', 'Australia']
>>> countries[-1]
'Australia'
>>> countries[-2]
'Brazil'
Python cũng cho phép thực hiện phép toán slice trên một nhóm phần tử. Hãy xem ví dụ sau:
Ví dụ
>>> countries = ['Russia', 'Canada', 'USA', 'China', 'Brazil', 'Australia']
>>> countries[3:5]
['China', 'Brazil']
>>> countries[0:3]
['Russia', 'Canada', 'USA']
>>> countries[:3]
['Russia', 'Canada', 'USA']
>>> countries[3:]
['China', 'Brazil', 'Australia']
>>> countries[:]
['Russia', 'Canada', 'USA', 'China', 'Brazil', 'Australia']
Ở đây chúng ta sử dụng phép toán căt đoạn (range slice) để trích ra một danh sách con.
Đế ý cấu trúc chung của phép toán cắt đoạn có dạng [start:stop]. Phép toán này sẽ trả lại một danh sách con, lấy từ phần tử có chỉ số start đến phần tử có chỉ số stop-1.
Như trong ví dụ trên, coutries[3:5] sẽ trả lại danh sách con lấy từ phần từ có chỉ số số 3 ('China') đến phần tử có chỉ số 5-1 ('Brazil').
Nếu start = 0 thì có thể bỏ qua (không cần viết), như trường hợp countries[:3]: countries[:3] tương đương với countries[0:3].
Nếu bỏ qua giá trị stop thì nó tương ứng với chỉ số của phần tử cuối cùng, như trường hợp countries[3:] sẽ trả về từ phần tử có chỉ số 3 đến hết danh sách. Cách thức này rất tiện lợi để lấy phần tử mà không cần biết số lượng phần tử.
Cá biệt, nếu bỏ qua cả start và stop thì coi như phép slice này trả lại danh sách con bằng danh sách gốc: countries[:].
start và stop có thể nhận giá trị âm với ý nghĩa là chỉ số tính từ cuối danh sách.
Ví dụ
>>> countries = ['Russia', 'Canada', 'USA', 'China', 'Brazil', 'Australia']
>>> countries[-1] # phần tử thứ nhất từ cuối
'Australia'
>>> countries[-2] # phần tử thứ hai từ cuối
'Brazil'
>>> countries[-1:] # danh sách con chứa phần tử cuối cùng
['Australia']
>>> countries[:-1] # danh sách con loại trừ phần tử cuối cùng
['Russia', 'Canada', 'USA', 'China', 'Brazil']
Với danh sách lồng nhau, bạn phải áp dụng phép toán slice cho cả danh sách con. Ví dụ
Ví dụ
>>> matrix = [[1, 2], [3, 4]]
>>> matrix[0] # trả lại phần tử 0 là một danh sách con
[1, 2]
>>> matrix[0][0] # trả lại phần tử 0 của danh sach con
1
>>> nested = ['Russia', 'Canada', 'USA', 'China', 'Brazil', [17.09, 9.9, 9.8, 9.5, 8.5]]
>>> nested[5] # phần tử số 5 là một danh sách
[17.09, 9.9, 9.8, 9.5, 8.5]
>>> nested[5][4] # lấy phần tử cuối cùng của danh sách con
8.5
Một khi đã truy xuất được phần tử mong muốn, bạn có thể thực hiện các thao tác như cập nhật hoặc xóa.
Thêm mới, cập nhật và xóa list
Để cập nhật, bạn chỉ việc gán giá trị mới cho phần tử được chọn.
Ví dụ
>>> countries = ['Russia', 'Canada', 'USA', 'China', 'Brazil', 'Australia']
>>> countries[0] = 'Vietnam' # cập nhật phần tử số 0 bằng 1 giá trị đơn mới
>>> countries
['Vietnam', 'Canada', 'USA', 'China', 'Brazil', 'Australia']
>>> countries[0] = ['Vietnam', 'Laos', 'Cambodia'] # cập nhật phần tử số 0 bằng một danh sách mới (tạo nested list)
>>> countries
[['Vietnam', 'Laos', 'Cambodia'], 'Canada', 'USA', 'China', 'Brazil', 'Australia']
>>> countries[0] = 'Russia' # cập nhật phần tử 0 (danh sách con) thành một phần tử đơn
>>> countries
['Russia', 'Canada', 'USA', 'China', 'Brazil', 'Australia']
>>> countries[1:3] = ['North America', 'South America'] # cập nhật danh sách con
>>> countries
['Russia', 'North America', 'South America', 'Brazil', 'Australia']
>>> countries[1:3] = ['America'] # cập nhật danh sách con
>>> countries
['Russia', 'America', 'China', 'Brazil', 'Australia']
Qua loạt ví dụ trên bạn có thể thấy sự linh hoạt của Python khi cập nhật danh sách. Bạn có thể cập nhật một phần tử hoặc một danh sách con bằng một phần tử hoặc danh sách con khác.
Để xóa, bạn dùng lệnh del trước phần tử cần xóa, trong đó phần tử cần xóa được lựa chọn bằng phép toán slice hoặc range slice. Ví dụ:
Ví dụ
>>> countries = ['Russia', 'Canada', 'USA', 'China', 'Brazil', 'Australia']
>>> del countries[0]
>>> countries
['Canada', 'USA', 'China', 'Brazil', 'Australia']
>>> del countries[:2]
>>> countries
['China', 'Brazil', 'Australia']
>>> del countries[1:]
>>> countries
['China']
Để thêm phần tử mới vào cuối danh sách, bạn có thể sử dụng phép cộng gán += hoặc phương thức append() như sau:
Ví dụ
>>> countries = ['China'] # danh sách gốc chỉ có China
>>> countries += ['Russia', 'USA', 'Canada'] # thêm vào cuối danh sách
>>> countries
['China', 'Russia', 'USA', 'Canada']
>>> countries.append('Brazil') # append() chỉ thêm được 1 phần tử
>>> countries
['China', 'Russia', 'USA', 'Canada', 'Brazil']
>>> countries.extend(['India', 'Argentina', 'Kazakhstan']) # extend thêm 1 danh sách
>>> countries
['China', 'Russia', 'USA', 'Canada', 'Brazil', 'India', 'Argentina', 'Kazakhstan']
Khi dùng append() bạn chỉ thêm được 1 phần tử. Nếu cần thêm một danh sách, hãy dùng phương thức extend().
Một số thao tác khác trên danh sách
Danh sách là một kiểu dữ liệu có thể duyệt (iterable). Do vậy bạn có thể dùng vòng for để duyệt danh sách như sau:
Ví dụ
>>> countries = ['Russia', 'Canada', 'USA', 'China', 'Brazil', 'Australia']
>>> for c in countries:
... print(c.upper())
...
RUSSIA
CANADA
USA
CHINA
BRAZIL
AUSTRALIA
Vòng lặp for sẽ tự động duyệt qua từng phần tử theo thứ tự và đặt giá trị tương ứng vào biến điều khiển. Bạn có thể sử dụng biến điều khiển trong vòng lặp. Trong ví dụ trên, mỗi tên quốc gia sẽ lần lượt đặt vào biến điều khiển c. Chúng ta chuyển nó thành chuỗi in hoa để in ra màn hình.
Danh sách hỗ trợ một số phép toán, bao gồm phép ghép danh sách <strong>+</strong>
, lặp danh sách *
, kiểm tra thành viên in.
Ví dụ
>>> # phép cộng tạo ra một danh sách mới từ các danh sách con
>>> companies = ['Google', 'Apple', 'Microsoft', 'Facebook'] + ['IBM', 'HP', 'Xerox', 'Canon']
>>> companies
['Google', 'Apple', 'Microsoft', 'Facebook', 'IBM', 'HP', 'Xerox', 'Canon']
>>> # phép nhân lặp lại các phần tử của danh sách để tạo thành danh sách mới
>>> haha = ['hah', 'hoh'] * 3
>>> haha
['hah', 'hoh', 'hah', 'hoh', 'hah', 'hoh']
>>> # phép toán kiểm tra thành viên
>>> countries = ['Russia', 'Canada', 'USA', 'China', 'Brazil', 'Australia']
>>> 'Russia' in countries
True
>>> 'Vietname' in countries
False
Ngoài các phép toán trên, Python cung cấp một số hàm làm việc với danh sách:
- len() – trả về số phần tử của danh sách.
- max() – trả về phần tử lớn nhất trong danh sách.
- min() – trả về phần tử nhỏ nhất của danh sách.
Ví dụ
>>> countries = ['Russia', 'Canada', 'USA', 'China', 'Brazil', 'Australia']
>>> len(countries)
6
>>> max(countries)
'USA'
>>> min(countries)
'Australia'
Các phương thức của lớp list
Do list là một class trong Python, nó cung cấp một số phương thức bạn có thể sử dụng. Hãy xem cách sử dụng các phương thức này qua các ví dụ sau:
Ví dụ
>>> languages = ['Python', 'Java', 'C/C++', 'Javascript', 'Go', 'R', 'Swift', 'PHP', 'C#']
>>> # append và extend bạn đã gặp ở trên
>>> languages.append('Visual Basic')
>>> languages
['Python', 'Java', 'C/C++', 'Javascript', 'Go', 'R', 'Swift', 'PHP', 'C#', 'Visual Basic']
>>> languages.extend(['Delphi', 'Pascal'])
>>> languages
['Python', 'Java', 'C/C++', 'Javascript', 'Go', 'R', 'Swift', 'PHP', 'C#', 'Visual Basic', 'Delphi', 'Pascal']
>>> # đếm xem một giá trị xuất hiện bao nhiêu lần
>>> languages.count('C#')
1
>>> # xác định chỉ số của một phần tử
>>> languages.index('Java')
1
>>> languages.index('Python')
0
>>> # hoạt động giống như pop trên stack: lấy ra phần tử cuối cùng và loại bỏ nó khỏi danh sách
>>> languages.pop()
'Pascal'
>>> languages.pop()
'Delphi'
>>> languages
['Python', 'Java', 'C/C++', 'Javascript', 'Go', 'R', 'Swift', 'PHP', 'C#', 'Visual Basic']
>>> # chèn 1 phần tử vào vị trí chỉ định
>>> languages.insert(0, 'Prolog') # chèn 'Prolog' vào vị trí số 0
>>> languages
['Prolog', 'Python', 'Java', 'C/C++', 'Javascript', 'Go', 'R', 'Swift', 'PHP', 'C#', 'Visual Basic']
>>> # loại bỏ 1 phần tử khỏi danh sách
>>> languages.remove('Prolog')
>>> languages
['Python', 'Java', 'C/C++', 'Javascript', 'Go', 'R', 'Swift', 'PHP', 'C#', 'Visual Basic']
>>> # đảo ngược vị trí các phần tử
>>> languages.reverse()
>>> languages
['Visual Basic', 'C#', 'PHP', 'Swift', 'R', 'Go', 'Javascript', 'C/C++', 'Java', 'Python']
>>> # sắp xếp danh sách
>>> languages.sort()
>>> languages
['C#', 'C/C++', 'Go', 'Java', 'Javascript', 'PHP', 'Python', 'R', 'Swift', 'Visual Basic']
Kết luận
Trong bài học này này chúng ta đã học chi tiết về kiểu dữ liệu tập hợp đầu tiên: list. Có thể thấy list trong Python là một kiểu dữ liệu rất đa năng và linh hoạt. Bạn có thể lưu trữ bất kỳ dữ liệu bên trong list. List cho phép thực hiện các thao tác thêm-sửa-xóa rất linh hoạt.