5. Cấu trúc dữ liệu¶
Chương này mô tả chi tiết hơn một số điều bạn đã học và cũng bổ sung thêm một số điều mới.
5.1. Thông tin thêm về danh sách¶
Kiểu dữ liệu list có thêm một số phương thức. Dưới đây là tất cả các phương thức của đối tượng danh sách:
- list.append(value, /)
Thêm một mục vào cuối danh sách. Tương tự với
a[len(a):] = [x]
- list.extend(iterable, /)
Mở rộng danh sách bằng cách nối thêm tất cả các mục từ iterable. Tương tự với
a[len(a):] = iterable
- list.insert(index, value, /)
Chèn một mục vào một vị trí nhất định. Đối số đầu tiên là chỉ mục của phần tử cần chèn vào trước, do đó,
a.insert(0, x)sẽ chèn vào đầu danh sách vàa.insert(len(a), x)tương đương vớia.append(x).
- list.remove(value, /)
Xóa mục đầu tiên khỏi danh sách có giá trị bằng value. Nó tăng
ValueErrornếu không có vật phẩm đó.
- list.pop(index=-1, /)
Xóa mục ở vị trí nhất định trong danh sách và trả lại. Nếu không có chỉ mục nào được chỉ định,
a.pop()sẽ xóa và trả về mục cuối cùng trong danh sách. Nó tăngIndexErrornếu danh sách trống hoặc chỉ mục nằm ngoài phạm vi danh sách.
- list.clear()
Xóa tất cả các mục khỏi danh sách. Tương tự với
del a[:]
- list.index(value[, start[, stop]])
Trả về chỉ mục dựa trên 0 của lần xuất hiện đầu tiên của value trong danh sách. Tăng
ValueErrornếu không có vật phẩm đó.Các đối số tùy chọn start và end được hiểu như trong ký hiệu lát cắt và được sử dụng để giới hạn tìm kiếm trong một chuỗi con cụ thể của danh sách. Chỉ số trả về được tính tương ứng với phần đầu của chuỗi đầy đủ thay vì đối số start.
- list.count(value, /)
Trả về số lần value xuất hiện trong danh sách.
- list.sort(*, key=None, reverse=False)
Sắp xếp các mục của danh sách tại chỗ (các đối số có thể được sử dụng để tùy chỉnh sắp xếp, xem
sorted()để biết phần giải thích).
- list.reverse()
Đảo ngược các phần tử của danh sách tại chỗ.
- list.copy()
Trả lại một bản sao nông của danh sách. Tương tự với
a[:]
Một ví dụ sử dụng hầu hết các phương thức danh sách
>>> trái cây = ['cam', 'táo', 'lê', 'chuối', 'kiwi', 'táo', 'chuối']
>>> trái cây.count('apple')
2
>>> trái cây.count('quýt')
0
>>> trái cây.index('chuối')
3
>>>fruit.index('banana', 4) # Find chuối tiếp theo bắt đầu từ vị trí 4
6
>>> trái cây.reverse()
>>> trái cây
['chuối', 'táo', 'kiwi', 'chuối', 'lê', 'táo', 'cam']
>>> trái cây.append('nho')
>>> trái cây
['chuối', 'táo', 'kiwi', 'chuối', 'lê', 'táo', 'cam', 'nho']
>>> trái cây.sort()
>>> trái cây
['táo', 'táo', 'chuối', 'chuối', 'nho', 'kiwi', 'cam', 'lê']
>>> trái cây.pop()
'quả lê'
Bạn có thể nhận thấy rằng các phương thức như insert, remove hoặc sort chỉ sửa đổi danh sách và không in ra giá trị trả về -- chúng trả về None mặc định. [1] Đây là nguyên tắc thiết kế cho tất cả các cấu trúc dữ liệu có thể thay đổi trong Python.
Một điều khác bạn có thể nhận thấy là không phải tất cả dữ liệu đều có thể được sắp xếp hoặc so sánh. Ví dụ: [None, 'hello', 10] không sắp xếp vì số nguyên không thể so sánh với chuỗi và None không thể so sánh với các loại khác. Ngoài ra, có một số loại không có mối quan hệ thứ tự xác định. Ví dụ: 3+4j < 5+7j không phải là sự so sánh hợp lệ.
5.1.1. Sử dụng danh sách làm ngăn xếp¶
Các phương thức danh sách giúp bạn dễ dàng sử dụng danh sách dưới dạng ngăn xếp, trong đó phần tử cuối cùng được thêm vào là phần tử đầu tiên được truy xuất ("vào sau, ra trước"). Để thêm một mục vào đầu ngăn xếp, hãy sử dụng append(). Để truy xuất một mục từ đầu ngăn xếp, hãy sử dụng pop() mà không có chỉ mục rõ ràng. Ví dụ:
>>> ngăn xếp = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> ngăn xếp
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> ngăn xếp
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> ngăn xếp
[3, 4]
5.1.2. Sử dụng danh sách làm hàng đợi¶
Cũng có thể sử dụng danh sách làm hàng đợi, trong đó phần tử đầu tiên được thêm vào là phần tử đầu tiên được truy xuất ("vào trước, ra trước"); tuy nhiên, danh sách không hiệu quả cho mục đích này. Trong khi việc thêm và bật lên từ cuối danh sách diễn ra nhanh, thì việc chèn hoặc bật lên từ đầu danh sách lại chậm (vì tất cả các phần tử khác phải được dịch chuyển bởi một phần tử).
Để triển khai hàng đợi, hãy sử dụng collections.deque được thiết kế để có thể thêm và bật nhanh từ cả hai đầu. Ví dụ:
>>> từ deque nhập bộ sưu tập
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry") # Terry đến
>>> queue.append("Graham") # Graham đến
>>> queue.popleft() # The người đầu tiên đến giờ đã rời đi
'Eric'
>>> queue.popleft() # The thứ hai đến nơi bây giờ sẽ rời đi
'John'
>>> xếp hàng # Remaining xếp hàng theo thứ tự đến
deque(['Michael', 'Terry', 'Graham'])
5.1.3. Danh sách hiểu¶
Việc hiểu danh sách cung cấp một cách ngắn gọn để tạo danh sách. Các ứng dụng phổ biến là tạo các danh sách mới trong đó mỗi phần tử là kết quả của một số thao tác được áp dụng cho từng thành viên của một chuỗi khác hoặc có thể lặp lại hoặc để tạo một chuỗi con gồm các phần tử đó thỏa mãn một điều kiện nhất định.
Ví dụ: giả sử chúng ta muốn tạo một danh sách các hình vuông, như:
>>> hình vuông = []
>>> cho x trong phạm vi (10):
... hình vuông.append(x**2)
...
>>> hình vuông
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Lưu ý rằng điều này tạo ra (hoặc ghi đè) một biến có tên x vẫn tồn tại sau khi vòng lặp hoàn thành. Chúng ta có thể tính toán danh sách các hình vuông mà không có bất kỳ tác dụng phụ nào bằng cách sử dụng
hình vuông = danh sách(map(lambda x: x**2, range(10)))
hoặc, tương đương:
hình vuông = [x**2 cho x trong phạm vi (10)]
ngắn gọn và dễ đọc hơn.
Việc hiểu danh sách bao gồm các dấu ngoặc chứa một biểu thức theo sau là mệnh đề for, sau đó là 0 hoặc nhiều mệnh đề for hoặc if. Kết quả sẽ là một danh sách mới từ việc đánh giá biểu thức trong ngữ cảnh của các mệnh đề for và if theo sau nó. Ví dụ: listcomp này kết hợp các thành phần của hai danh sách nếu chúng không bằng nhau:
>>> [(x, y) cho x trong [1,2,3] cho y trong [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
và nó tương đương với:
>>> lược = []
>>> cho x trong [1,2,3]:
... cho y trong [3,1,4]:
... nếu x != y:
... combs.append((x, y))
...
>>> lược
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
Lưu ý thứ tự của câu lệnh for và if giống nhau như thế nào trong cả hai đoạn mã này.
Nếu biểu thức là một bộ dữ liệu (ví dụ: (x, y) trong ví dụ trước), thì nó phải được đặt trong ngoặc đơn.
>>> vec = [-4, -2, 0, 2, 4]
>>> # create một danh sách mới với giá trị được nhân đôi
>>> [x*2 cho x trong vec]
[-8, -4, 0, 4, 8]
>>> # filter danh sách loại trừ số âm
>>> [x cho x trong vec nếu x >= 0]
[0, 2, 4]
>>> # apply một hàm cho tất cả các phần tử
>>> [abs(x) cho x trong vec]
[4, 2, 0, 2, 4]
>>> # call một phương thức trên mỗi phần tử
>>> trái cây tươi = ['chuối', 'loganberry', 'chanh leo']
>>> [weapon.strip() cho vũ khí trong trái cây tươi]
['chuối', 'loganberry', 'chanh leo']
>>> # create danh sách 2 bộ như (số, hình vuông)
>>> [(x, x**2) cho x trong phạm vi (6)]
[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
>>> Bộ # the phải được đặt trong ngoặc đơn, nếu không sẽ xảy ra lỗi
>>> [x, x**2 cho x trong phạm vi(6)]
Tệp "<stdin>", dòng 1
[x, x**2 cho x trong phạm vi (6)]
^^ ^^^ ^^
Cú phápError: bạn có quên dấu ngoặc đơn xung quanh mục tiêu hiểu không?
>>> # flatten một danh sách sử dụng listcomp có hai 'for'
>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num cho phần tử trong vec cho số trong phần tử]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Việc hiểu danh sách có thể chứa các biểu thức phức tạp và các hàm lồng nhau
>>> từ toán nhập pi
>>> [str(round(pi, i)) cho i trong phạm vi (1, 6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']
5.1.4. Hiểu danh sách lồng nhau¶
Biểu thức ban đầu trong quá trình hiểu danh sách có thể là bất kỳ biểu thức tùy ý nào, bao gồm cả một biểu thức hiểu danh sách khác.
Hãy xem xét ví dụ sau về ma trận 3x4 được triển khai dưới dạng danh sách gồm 3 danh sách có độ dài 4
>>> ma trận = [
... [1, 2, 3, 4],
... [5, 6, 7, 8],
... [9, 10, 11, 12],
...]
Việc hiểu danh sách sau đây sẽ chuyển đổi hàng và cột
>>> [[hàng[i] cho hàng trong ma trận] cho i trong phạm vi (4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
Như chúng ta đã thấy trong phần trước, khả năng hiểu danh sách bên trong được đánh giá trong ngữ cảnh của for theo sau nó, vì vậy ví dụ này tương đương với:
>>> chuyển đổi = []
>>> cho i trong phạm vi (4):
... transpose.append([row[i] cho hàng trong ma trận])
...
>>> chuyển đổi
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
đến lượt nó, giống như:
>>> chuyển đổi = []
>>> cho i trong phạm vi (4):
... # the 3 dòng sau triển khai listcomp lồng nhau
... chuyển_row = []
... cho hàng trong ma trận:
... transpose_row.append(row[i])
... transpose.append(transpose_row)
...
>>> chuyển đổi
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
Trong thế giới thực, bạn nên ưu tiên các hàm dựng sẵn hơn là các câu lệnh luồng phức tạp. Hàm zip() sẽ hoạt động rất tốt cho trường hợp sử dụng này
>>> danh sách(zip(*ma trận))
[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]
Xem Giải nén danh sách đối số để biết chi tiết về dấu hoa thị ở dòng này.
5.2. Tuyên bố del¶
Có một cách để xóa một mục khỏi danh sách dựa trên chỉ mục của nó thay vì giá trị của nó: câu lệnh del. Điều này khác với phương thức pop() trả về một giá trị. Câu lệnh del cũng có thể được sử dụng để xóa các lát khỏi danh sách hoặc xóa toàn bộ danh sách (điều mà chúng ta đã thực hiện trước đó bằng cách gán một danh sách trống cho lát). Ví dụ:
>>> a = [-1, 1, 66,25, 333, 333, 1234,5]
>>> del a[0]
>>> một
[1, 66,25, 333, 333, 1234,5]
>>> del a[2:4]
>>> một
[1, 66,25, 1234,5]
>>> del a[:]
>>> một
[]
del cũng có thể được sử dụng để xóa toàn bộ biến
>>> del a
Việc tham chiếu tên a sau đây là một lỗi (ít nhất là cho đến khi một giá trị khác được gán cho nó). Chúng ta sẽ tìm thấy những cách sử dụng khác của del sau.
5.3. Bộ dữ liệu và trình tự¶
Chúng ta đã thấy rằng danh sách và chuỗi có nhiều thuộc tính chung, chẳng hạn như các thao tác lập chỉ mục và cắt lát. Chúng là hai ví dụ về kiểu dữ liệu sequence (xem Các loại trình tự --- list, tuple, range). Vì Python là ngôn ngữ đang phát triển nên các kiểu dữ liệu chuỗi khác có thể được thêm vào. Ngoài ra còn có một kiểu dữ liệu chuỗi tiêu chuẩn khác: tuple.
Một bộ dữ liệu bao gồm một số giá trị được phân tách bằng dấu phẩy, ví dụ:
>>> t = 12345, 54321, 'xin chào!'
>>> t[0]
12345
>>> t
(12345, 54321, 'xin chào!')
>>> # Tuples có thể được lồng vào nhau:
>>> u = t, (1, 2, 3, 4, 5)
>>> bạn
((12345, 54321, 'xin chào!'), (1, 2, 3, 4, 5))
>>> # Tuples là bất biến:
>>> t[0] = 88888
Traceback (cuộc gọi gần đây nhất):
Tệp "<stdin>", dòng 1, trong <module>
TypeError: đối tượng 'tuple' không hỗ trợ gán mục
>>> # but chúng có thể chứa các đối tượng có thể thay đổi:
>>> v = ([1, 2, 3], [3, 2, 1])
>>> v
([1, 2, 3], [3, 2, 1])
Như bạn thấy, trên đầu ra, các bộ dữ liệu luôn được đặt trong dấu ngoặc đơn để các bộ dữ liệu lồng nhau được diễn giải chính xác; chúng có thể được nhập vào có hoặc không có dấu ngoặc đơn xung quanh, mặc dù thường thì dấu ngoặc đơn cũng cần thiết (nếu bộ dữ liệu là một phần của biểu thức lớn hơn). Không thể gán cho các mục riêng lẻ của một bộ dữ liệu, tuy nhiên có thể tạo các bộ dữ liệu chứa các đối tượng có thể thay đổi, chẳng hạn như danh sách.
Mặc dù các bộ dữ liệu có vẻ giống với danh sách nhưng chúng thường được sử dụng trong các tình huống khác nhau và cho các mục đích khác nhau. Các bộ dữ liệu là immutable và thường chứa một chuỗi các phần tử không đồng nhất được truy cập thông qua việc giải nén (xem phần sau trong phần này) hoặc lập chỉ mục (hoặc thậm chí theo thuộc tính trong trường hợp namedtuples). Danh sách là mutable và các phần tử của chúng thường đồng nhất và được truy cập bằng cách lặp qua danh sách.
Một vấn đề đặc biệt là việc xây dựng các bộ dữ liệu chứa 0 hoặc 1 mục: cú pháp có một số đặc điểm bổ sung để đáp ứng các mục này. Các bộ dữ liệu trống được tạo bởi một cặp dấu ngoặc đơn trống; một bộ dữ liệu có một mục được xây dựng bằng cách theo sau một giá trị bằng dấu phẩy (việc đặt một giá trị trong ngoặc đơn là không đủ). Xấu xí, nhưng hiệu quả. Ví dụ:
>>> trống = ()
>>> singleton = 'hello', # <- lưu ý dấu phẩy ở cuối
>>> len(trống)
0
>>> len(singleton)
1
>>> người độc thân
('xin chào',)
Câu lệnh t = 12345, 54321, 'hello!' là một ví dụ về tuple packing: các giá trị 12345, 54321 và 'hello!' được gói cùng nhau trong một bộ dữ liệu. Hoạt động ngược lại cũng có thể thực hiện được:
>>> x, y, z = t
Điều này được gọi một cách thích hợp là sequence unpacking và hoạt động với bất kỳ chuỗi nào ở phía bên phải. Việc giải nén chuỗi yêu cầu có nhiều biến ở bên trái dấu bằng bằng số phần tử trong chuỗi. Lưu ý rằng phép gán nhiều lần thực chất chỉ là sự kết hợp của việc đóng gói bộ và giải nén theo trình tự.
5.4. bộ¶
Python cũng bao gồm một kiểu dữ liệu cho sets. Tập hợp là một bộ sưu tập không có thứ tự và không có phần tử trùng lặp. Sử dụng cơ bản bao gồm kiểm tra tư cách thành viên và loại bỏ các mục trùng lặp. Các đối tượng tập hợp cũng hỗ trợ các phép toán như hợp, giao, hiệu và hiệu đối xứng.
Các dấu ngoặc nhọn hoặc hàm set() có thể được sử dụng để tạo các bộ. Lưu ý: để tạo một tập hợp trống bạn phải sử dụng set(), không phải {}; cái sau tạo ra một từ điển trống, một cấu trúc dữ liệu mà chúng ta sẽ thảo luận trong phần tiếp theo.
Vì các tập hợp không có thứ tự nên việc lặp lại chúng hoặc in chúng có thể tạo ra các phần tử theo thứ tự khác với thứ bạn mong đợi.
Đây là một minh chứng ngắn gọn:
>>> giỏ = {'táo', 'cam', 'táo', 'lê', 'cam', 'chuối'}
>>> print(basket) # show các bản sao đã bị xóa
{'cam', 'chuối', 'lê', 'táo'}
>>> 'cam' trong giỏ thử nghiệm thành viên # fast
đúng
>>> 'cỏ cua' trong giỏ
sai
>>> # Demonstrate thiết lập các thao tác trên các chữ cái duy nhất trong hai từ
>>>
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> một chữ cái # unique trong một
{'a', 'r', 'b', 'c', 'd'}
>>> a - b # letters ở a nhưng không ở b
{'r', 'd', 'b'}
>>> một | b # letters ở a hoặc b hoặc cả hai
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b # letters ở cả a và b
{'a', 'c'}
>>> a ^ b # letters ở a hoặc b nhưng không phải cả hai
{'r', 'd', 'b', 'm', 'z', 'l'}
Tương tự như list comprehensions, việc hiểu tập hợp cũng được hỗ trợ
>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> một
{'r', 'd'}
5.5. Từ điển¶
Một kiểu dữ liệu hữu ích khác được tích hợp trong Python là dictionary (xem Các loại ánh xạ --- dict). Từ điển đôi khi được tìm thấy trong các ngôn ngữ khác dưới dạng "ký ức liên kết" hoặc "mảng liên kết". Không giống như các chuỗi được lập chỉ mục theo một dãy số, từ điển được lập chỉ mục theo keys, có thể là bất kỳ loại bất biến nào; chuỗi và số luôn có thể là khóa. Các bộ dữ liệu có thể được sử dụng làm khóa nếu chúng chỉ chứa chuỗi, số hoặc bộ dữ liệu; nếu một tuple chứa bất kỳ đối tượng có thể thay đổi nào trực tiếp hoặc gián tiếp thì nó không thể được sử dụng làm khóa. Bạn không thể sử dụng danh sách làm khóa vì danh sách có thể được sửa đổi tại chỗ bằng cách sử dụng phép gán chỉ mục, phép gán lát hoặc các phương thức như append() và extend().
Tốt nhất nên coi từ điển là một tập hợp các cặp key: value, với yêu cầu các khóa là duy nhất (trong một từ điển). Một cặp dấu ngoặc nhọn tạo ra một từ điển trống: {}. Việc đặt danh sách các cặp khóa:giá trị được phân tách bằng dấu phẩy trong dấu ngoặc nhọn sẽ thêm các cặp khóa:giá trị ban đầu vào từ điển; đây cũng là cách từ điển được viết trên đầu ra.
Các thao tác chính trên từ điển là lưu trữ một giá trị bằng một số khóa và trích xuất giá trị đã cho từ khóa đó. Cũng có thể xóa cặp khóa:giá trị bằng del. Nếu bạn lưu trữ bằng khóa đã được sử dụng thì giá trị cũ được liên kết với khóa đó sẽ bị lãng quên.
Trích xuất một giá trị cho khóa không tồn tại bằng cách đăng ký (d[key]) sẽ tăng KeyError. Để tránh gặp phải lỗi này khi cố gắng truy cập vào một khóa có thể không tồn tại, hãy sử dụng phương thức get() để trả về None (hoặc một giá trị mặc định được chỉ định) nếu khóa đó không có trong từ điển.
Thực hiện list(d) trên từ điển sẽ trả về danh sách tất cả các khóa được sử dụng trong từ điển, theo thứ tự chèn (nếu bạn muốn sắp xếp nó, thay vào đó chỉ cần sử dụng sorted(d)). Để kiểm tra xem một khóa có trong từ điển hay không, hãy sử dụng từ khóa in.
Đây là một ví dụ nhỏ sử dụng từ điển:
>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> điện thoại
{'jack': 4098, 'sape': 4139, 'guido': 4127}
>>> tel['jack']
4098
>>> điện thoại['irv']
Traceback (cuộc gọi gần đây nhất):
Tệp "<stdin>", dòng 1, trong <module>
Lỗi khóa: 'irv'
>>> print(tel.get('irv'))
không có
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> điện thoại
{'jack': 4098, 'guido': 4127, 'irv': 4127}
>>> danh sách(tel)
['jack', 'guido', 'irv']
>>> sắp xếp(tel)
['guido', 'irv', 'jack']
>>> 'hướng dẫn' trong điện thoại
đúng
>>> 'jack' không có trong điện thoại
sai
Hàm tạo dict() xây dựng từ điển trực tiếp từ chuỗi các cặp khóa-giá trị
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'guido': 4127, 'jack': 4098}
Ngoài ra, khả năng hiểu chính tả có thể được sử dụng để tạo từ điển từ các biểu thức khóa và giá trị tùy ý
>>> {x: x**2 cho x trong (2, 4, 6)}
{2: 4, 4: 16, 6: 36}
Khi các khóa là các chuỗi đơn giản, đôi khi việc chỉ định các cặp bằng cách sử dụng đối số từ khóa sẽ dễ dàng hơn:
>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'guido': 4127, 'jack': 4098}
5.6. Kỹ thuật lặp¶
Khi lặp qua từ điển, khóa và giá trị tương ứng có thể được truy xuất cùng lúc bằng phương pháp items().
>>> hiệp sĩ = {'gallahad': 'trong sáng', 'robin': 'dũng cảm'}
>>> cho k, v trong Knights.items():
... in(k, v)
...
galahad sự tinh khiết
Robin dũng cảm
Khi lặp qua một chuỗi, chỉ số vị trí và giá trị tương ứng có thể được truy xuất cùng lúc bằng hàm enumerate().
>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... in(i, v)
...
0 tic
1 tắc
2 ngón chân
Để lặp qua hai hoặc nhiều chuỗi cùng lúc, các mục có thể được ghép nối với chức năng zip().
>>> câu hỏi = ['tên', 'nhiệm vụ', 'màu sắc yêu thích']
>>> đáp án = ['lancelot', 'chén thánh', 'blue']
>>> for q, a in zip(câu hỏi, câu trả lời):
... print('{0} của bạn là gì? Đó là {1}.'.format(q, a))
...
Tên bạn là gì? Đó là cây thương.
Nhiệm vụ của bạn là gì? Đó là chén thánh.
Màu sắc yêu thích của bạn là gì? Nó có màu xanh.
Để lặp lại một chuỗi theo chiều ngược lại, trước tiên hãy chỉ định chuỗi theo hướng thuận và sau đó gọi hàm reversed().
>>> for i in Reverse(range(1, 10, 2)):
... in(i)
...
9
7
5
3
1
Để lặp lại một chuỗi theo thứ tự đã sắp xếp, hãy sử dụng hàm sorted() để trả về một danh sách được sắp xếp mới trong khi nguồn không bị thay đổi.
>>> giỏ = ['táo', 'cam', 'táo', 'lê', 'cam', 'chuối']
>>> cho tôi trong đã sắp xếp(giỏ):
... in(i)
...
táo
táo
chuối
trái cam
trái cam
quả lê
Sử dụng set() trên một chuỗi sẽ loại bỏ các phần tử trùng lặp. Việc sử dụng sorted() kết hợp với set() trên một chuỗi là một cách thông thường để lặp lại các phần tử duy nhất của chuỗi theo thứ tự được sắp xếp.
>>> giỏ = ['táo', 'cam', 'táo', 'lê', 'cam', 'chuối']
>>> cho f trong được sắp xếp(set(basket)):
... in(f)
...
táo
chuối
trái cam
quả lê
Đôi khi bạn muốn thay đổi một danh sách trong khi lặp lại nó; tuy nhiên, thay vào đó, việc tạo danh sách mới thường đơn giản và an toàn hơn.
>>> nhập toán
>>> raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]
>>> dữ liệu đã lọc = []
>>> cho giá trị trong raw_data:
... nếu không phải math.isnan(value):
... đã lọc_data.append(giá trị)
...
>>> dữ liệu được lọc
[56,2, 51,7, 55,3, 52,5, 47,8]
5.7. Thông tin thêm về Điều kiện¶
Các điều kiện được sử dụng trong câu lệnh while và if có thể chứa bất kỳ toán tử nào, không chỉ các phép so sánh.
Toán tử so sánh in và not in là các phép kiểm tra tư cách thành viên nhằm xác định xem một giá trị có nằm trong (hoặc không nằm trong) một vùng chứa hay không. Các toán tử is và is not so sánh xem hai đối tượng có thực sự là một đối tượng hay không. Tất cả các toán tử so sánh đều có cùng mức ưu tiên, thấp hơn mức ưu tiên của tất cả các toán tử số.
So sánh có thể được xâu chuỗi. Ví dụ: a < b == c kiểm tra xem a có nhỏ hơn b hay không và hơn nữa b có bằng c hay không.
Các phép so sánh có thể được kết hợp bằng cách sử dụng các toán tử Boolean and và or, và kết quả của phép so sánh (hoặc của bất kỳ biểu thức Boolean nào khác) có thể bị phủ định bằng not. Chúng có mức độ ưu tiên thấp hơn toán tử so sánh; giữa chúng, not có mức độ ưu tiên cao nhất và or có mức ưu tiên thấp nhất, do đó A and not B or C tương đương với (A and (not B)) or C. Như mọi khi, có thể sử dụng dấu ngoặc đơn để thể hiện bố cục mong muốn.
Các toán tử Boolean and và or còn được gọi là toán tử short-circuit: các đối số của chúng được đánh giá từ trái sang phải và việc đánh giá sẽ dừng ngay khi kết quả được xác định. Ví dụ: nếu A và C đúng nhưng B sai thì A and B and C không đánh giá biểu thức C. Khi được sử dụng làm giá trị chung chứ không phải dưới dạng Boolean, giá trị trả về của toán tử đoản mạch là đối số được đánh giá cuối cùng.
Có thể gán kết quả so sánh hoặc biểu thức Boolean khác cho một biến. Ví dụ,
>>> string1, string2, string3 = '', 'Trondheim', 'Vũ điệu búa'
>>> non_null = string1 hoặc string2 hoặc string3
>>> non_null
'Trondheim'
Lưu ý rằng trong Python, không giống như C, việc gán bên trong các biểu thức phải được thực hiện rõ ràng bằng walrus operator :=. Điều này tránh được một loại vấn đề thường gặp trong các chương trình C: gõ = vào một biểu thức khi == được dự định.
5.8. So sánh trình tự và các loại khác¶
Các đối tượng trình tự thường có thể được so sánh với các đối tượng khác có cùng loại trình tự. Việc so sánh sử dụng thứ tự lexicographical: đầu tiên, hai mục đầu tiên được so sánh và nếu chúng khác nhau thì điều này sẽ xác định kết quả so sánh; nếu chúng bằng nhau thì hai mục tiếp theo sẽ được so sánh, v.v., cho đến khi hết một trong hai chuỗi. Nếu hai mục được so sánh là các chuỗi cùng loại thì việc so sánh từ điển được thực hiện theo cách đệ quy. Nếu tất cả các phần tử của hai chuỗi so sánh bằng nhau thì các chuỗi đó được coi là bằng nhau. Nếu một chuỗi là chuỗi con ban đầu của chuỗi kia thì chuỗi ngắn hơn sẽ là chuỗi nhỏ hơn (nhỏ hơn). Thứ tự từ điển cho chuỗi sử dụng số điểm mã Unicode để sắp xếp các ký tự riêng lẻ. Một số ví dụ về so sánh giữa các chuỗi cùng loại:
(1, 2, 3) < (1, 2, 4)
[1, 2, 3] < [1, 2, 4]
'ABC' < 'C' < 'Pascal' < 'Python'
(1, 2, 3, 4) < (1, 2, 4)
(1, 2) < (1, 2, -1)
(1, 2, 3) == (1.0, 2.0, 3.0)
(1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)
Lưu ý rằng việc so sánh các đối tượng thuộc các loại khác nhau với < hoặc > là hợp pháp với điều kiện các đối tượng đó có phương pháp so sánh phù hợp. Ví dụ: các loại số hỗn hợp được so sánh theo giá trị số của chúng, do đó 0 bằng 0,0, v.v. Mặt khác, thay vì cung cấp thứ tự tùy ý, trình thông dịch sẽ đưa ra ngoại lệ TypeError.
Chú thích cuối trang