Mỗi khóa được phân tách khỏi giá trị của nó bằng dấu hai chấm [. ], các mục được phân tách bằng dấu phẩy và toàn bộ nội dung được đặt trong dấu ngoặc nhọn. Một từ điển trống không có bất kỳ mục nào được viết chỉ bằng hai dấu ngoặc nhọn, như thế này. {}
Các khóa là duy nhất trong một từ điển trong khi các giá trị có thể không. Các giá trị của từ điển có thể thuộc bất kỳ loại nào, nhưng các khóa phải thuộc loại dữ liệu bất biến, chẳng hạn như chuỗi, số hoặc bộ dữ liệu
Truy cập các giá trị trong từ điển
Để truy cập các phần tử từ điển, bạn có thể sử dụng dấu ngoặc vuông quen thuộc cùng với khóa để lấy giá trị của nó. Sau đây là một ví dụ đơn giản -
#!/usr/bin/python dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'} print "dict['Name']: ", dict['Name'] print "dict['Age']: ", dict['Age']
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
dict['Name']: Zara dict['Age']: 7
Nếu chúng tôi cố gắng truy cập một mục dữ liệu bằng một khóa không phải là một phần của từ điển, chúng tôi sẽ gặp lỗi như sau -
#!/usr/bin/python dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'} print "dict['Alice']: ", dict['Alice']
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
dict['Alice']: Traceback [most recent call last]: File "test.py", line 4, in print "dict['Alice']: ", dict['Alice']; KeyError: 'Alice'
cập nhật từ điển
Bạn có thể cập nhật từ điển bằng cách thêm một mục mới hoặc một cặp khóa-giá trị, sửa đổi một mục hiện có hoặc xóa một mục hiện có như minh họa bên dưới trong ví dụ đơn giản –
#!/usr/bin/python dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'} dict['Age'] = 8; # update existing entry dict['School'] = "DPS School"; # Add new entry print "dict['Age']: ", dict['Age'] print "dict['School']: ", dict['School']
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
dict['Age']: 8 dict['School']: DPS School
Xóa các thành phần từ điển
Bạn có thể xóa các thành phần từ điển riêng lẻ hoặc xóa toàn bộ nội dung của từ điển. Bạn cũng có thể xóa toàn bộ từ điển trong một thao tác
Để xóa toàn bộ từ điển một cách rõ ràng, chỉ cần sử dụng câu lệnh del. Sau đây là một ví dụ đơn giản -
#!/usr/bin/python dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'} del dict['Name']; # remove entry with key 'Name' dict.clear[]; # remove all entries in dict del dict ; # delete entire dictionary print "dict['Age']: ", dict['Age'] print "dict['School']: ", dict['School']
Điều này tạo ra kết quả sau. Lưu ý rằng một ngoại lệ được đưa ra bởi vì sau khi từ điển del dict không còn tồn tại nữa -
dict['Age']: Traceback [most recent call last]: File "test.py", line 8, in print "dict['Age']: ", dict['Age']; TypeError: 'type' object is unsubscriptable
Lưu ý - phương thức del[] được thảo luận trong phần tiếp theo
Thuộc tính của khóa từ điển
Giá trị từ điển không có hạn chế. Chúng có thể là bất kỳ đối tượng Python tùy ý nào, đối tượng tiêu chuẩn hoặc đối tượng do người dùng định nghĩa. Tuy nhiên, điều tương tự cũng không đúng với các phím
Có hai điểm quan trọng cần nhớ về khóa từ điển -
[a] Không được phép nhập nhiều hơn một mục trên mỗi khóa. Điều đó có nghĩa là không cho phép khóa trùng lặp. Khi gặp phải các khóa trùng lặp trong quá trình gán, nhiệm vụ cuối cùng sẽ thắng. Ví dụ -
________số 8Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
dict['Name']: Manni
[b] Khóa phải là bất biến. Điều đó có nghĩa là bạn có thể sử dụng chuỗi, số hoặc bộ dữ liệu làm khóa từ điển nhưng không được phép sử dụng những thứ như ['key']. Sau đây là một ví dụ đơn giản -
dict['Name']: Zara dict['Age']: 70
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -
dict['Name']: Zara dict['Age']: 71
Các chức năng & phương pháp từ điển tích hợp
Python bao gồm các chức năng từ điển sau -
Sr. Không. Chức năng với Description1cmp[dict1, dict2]So sánh các yếu tố của cả dict
2len[chính tả]Cung cấp tổng chiều dài của từ điển. Điều này sẽ bằng với số lượng mục trong từ điển
3str[chính tả]Tạo một biểu diễn chuỗi có thể in được của một từ điển
4 loại [biến]Trả về kiểu của biến đã truyền. Nếu biến được truyền là từ điển thì nó sẽ trả về kiểu từ điển
Yêu cầu duy nhất đối với khóa từ điển là khóa đó có thể băm được. Các loại có thể thay đổi như danh sách, từ điển và bộ sẽ không hoạt động và dẫn đến lỗi như TypeError. loại không thể băm. 'dict'. nguồn
Những người mới sử dụng Python thường thắc mắc tại sao, trong khi ngôn ngữ này bao gồm cả bộ dữ liệu và loại danh sách, bộ dữ liệu có thể được sử dụng làm khóa từ điển, trong khi danh sách thì không. Đây là một quyết định thiết kế có chủ ý và có thể được giải thích tốt nhất bằng cách hiểu cách thức hoạt động của từ điển Python
Từ điển hoạt động như thế nào
Từ điển, trong Python, còn được gọi là "ánh xạ", bởi vì chúng "ánh xạ" hoặc "liên kết" các đối tượng chính với các đối tượng giá trị
Do đó, ánh xạ Python phải có khả năng, với một đối tượng khóa cụ thể, xác định đối tượng giá trị nào [nếu có] được liên kết với một khóa đã cho. Một cách tiếp cận đơn giản là lưu trữ danh sách các cặp [khóa, giá trị], sau đó tìm kiếm danh sách một cách tuần tự mỗi khi một giá trị được yêu cầu. Tuy nhiên, cách tiếp cận này sẽ rất chậm với số lượng lớn các mục - về độ phức tạp, thuật toán này sẽ là O[n], trong đó n là số lượng mục trong ánh xạ
Việc triển khai từ điển của Python giảm độ phức tạp trung bình của việc tra cứu từ điển xuống O[1] bằng cách yêu cầu các đối tượng chính đó cung cấp hàm "băm". Hàm băm như vậy lấy thông tin trong một đối tượng chính và sử dụng nó để tạo ra một số nguyên, được gọi là giá trị băm. Giá trị băm này sau đó được sử dụng để xác định cặp "nhóm" [khóa, giá trị] này sẽ được đặt vào. Mã giả cho chức năng tra cứu này có thể trông giống như
Để thuật toán tra cứu như vậy hoạt động chính xác, các hàm băm được cung cấp phải đảm bảo rằng nếu hai khóa tạo ra các giá trị băm khác nhau thì hai đối tượng khóa không tương đương, nghĩa là,
dict['Name']: Zara dict['Age']: 72
Mặt khác, việc kiểm tra giá trị băm của một đối tượng chính có thể khiến chúng ta tìm sai nhóm và do đó không bao giờ tìm thấy giá trị liên quan
Để thuật toán tra cứu như vậy hoạt động hiệu quả, hầu hết các nhóm chỉ nên có một số lượng nhỏ các mục [tốt nhất là chỉ có một mục]. Xem xét điều gì sẽ xảy ra với hàm băm sau
Lưu ý rằng hàm này đáp ứng các yêu cầu của hàm băm - mỗi khi hai khóa có giá trị băm khác nhau, chúng sẽ đại diện cho các đối tượng khác nhau. [Điều này đúng một cách tầm thường vì không có khóa nào có giá trị băm khác nhau - tất cả chúng đều có giá trị 1. ] Nhưng đây là một hàm băm tồi vì nó có nghĩa là tất cả các cặp [khóa, giá trị] sẽ được đặt trong một danh sách duy nhất và do đó, mỗi lần tra cứu sẽ yêu cầu tìm kiếm toàn bộ danh sách này. Do đó, một thuộc tính mong muốn [rất] của hàm băm là nếu hai khóa tạo ra các giá trị băm giống nhau, thì các đối tượng khóa là tương đương, nghĩa là,
dict['Name']: Zara dict['Age']: 73
Các hàm băm có thể ước lượng tốt thuộc tính này sẽ phân phối đồng đều các cặp [khóa, giá trị] trên các nhóm và giảm thời gian tra cứu
Các loại có thể sử dụng làm khóa từ điển
Cuộc thảo luận ở trên sẽ giải thích tại sao Python yêu cầu điều đó
Để được sử dụng làm khóa từ điển, một đối tượng phải hỗ trợ hàm băm [e. g. đến __hash__], so sánh bình đẳng [e. g. thông qua __eq__ hoặc __cmp__] và phải thỏa mãn điều kiện đúng ở trên
Danh sách dưới dạng khóa từ điển
Điều đó nói rằng, câu trả lời đơn giản cho lý do tại sao danh sách không thể được sử dụng làm khóa từ điển là danh sách không cung cấp phương thức __hash__ hợp lệ. Tất nhiên, câu hỏi rõ ràng là, "Tại sao không?"
Xem xét những loại hàm băm nào có thể được cung cấp cho danh sách
Nếu các danh sách được băm theo id, điều này chắc chắn sẽ hợp lệ theo định nghĩa của hàm băm của Python - các danh sách có giá trị băm khác nhau sẽ có các id khác nhau. Nhưng danh sách là vùng chứa và hầu hết các hoạt động khác trên chúng đều xử lý chúng như vậy. Vì vậy, danh sách băm theo id của chúng thay vào đó sẽ tạo ra hành vi không mong muốn, chẳng hạn như
Tra cứu các danh sách khác nhau có cùng nội dung sẽ tạo ra các kết quả khác nhau, mặc dù so sánh các danh sách có cùng nội dung sẽ chỉ ra chúng là tương đương
Sử dụng một danh sách theo nghĩa đen trong tra cứu từ điển sẽ là vô nghĩa -- nó sẽ luôn tạo ra KeyError
Nếu các danh sách được băm theo nội dung của chúng [như các bộ dữ liệu], thì đây cũng sẽ là một hàm băm hợp lệ - các danh sách có giá trị băm khác nhau sẽ có nội dung khác nhau. Vì vậy, một lần nữa, vấn đề không nằm ở định nghĩa của hàm băm. Nhưng điều gì sẽ xảy ra khi một danh sách, được sử dụng làm khóa từ điển, bị sửa đổi? . Điều này có thể dẫn đến các lỗi không mong muốn như
dict['Name']: Zara dict['Age']: 74
trong đó giá trị 42 không còn nữa vì danh sách băm thành cùng một giá trị, [1, 2], không tương đương với danh sách đã sửa đổi và giá trị tương đương với danh sách đã sửa đổi, [1, 2, 3] . Vì từ điển không biết khi nào một đối tượng khóa được sửa đổi, nên các lỗi như vậy chỉ có thể được tạo ra khi tra cứu khóa chứ không phải tại thời điểm sửa đổi đối tượng, điều này có thể khiến các lỗi như vậy khá khó gỡ lỗi
Nhận thấy rằng cả hai cách băm danh sách đều có một số tác dụng phụ không mong muốn, rõ ràng hơn là tại sao Python có lập trường rằng
Không nên sử dụng loại danh sách tích hợp làm khóa từ điển
Lưu ý rằng vì các bộ dữ liệu là bất biến, nên chúng không gặp rắc rối với danh sách - chúng có thể được băm theo nội dung của chúng mà không phải lo lắng về việc sửa đổi. Do đó, trong Python, chúng cung cấp phương thức __hash__ hợp lệ và do đó có thể sử dụng làm khóa từ điển
Các loại do người dùng xác định làm khóa từ điển
Còn các trường hợp của các loại do người dùng xác định thì sao?
Theo mặc định, tất cả các loại do người dùng xác định đều có thể sử dụng làm khóa từ điển với hash[object] mặc định là id[object] và cmp[object1, object2] mặc định là cmp[id[object1], id[object2]]. Đề xuất tương tự này đã được thảo luận ở trên cho các danh sách và thấy không đạt yêu cầu. Tại sao các loại do người dùng xác định lại khác nhau?
- Trong trường hợp một đối tượng phải được đặt trong ánh xạ, nhận dạng đối tượng thường quan trọng hơn nhiều so với nội dung đối tượng
Trong trường hợp nội dung đối tượng thực sự quan trọng, cài đặt mặc định có thể được xác định lại bằng cách ghi đè __hash__ và __cmp__ hoặc __eq__
Lưu ý rằng cách thực hành tốt hơn thường là khi một đối tượng được liên kết với một giá trị, chỉ cần gán giá trị đó làm một trong các thuộc tính của đối tượng