Bạn có thể sử dụng một đối tượng làm khóa trong python không?

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ố 8

Khi đ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']:  7
0

Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau -

dict['Name']:  Zara
dict['Age']:  7
1

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']:  7
2

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']:  7
3

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']:  7
4

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?

  1. 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
  2. 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

Cái gì có thể được sử dụng làm khóa trong Python?

Chuỗi, số và bộ hoạt động như khóa và bất kỳ loại nào cũng có thể là giá trị. Các loại khác có thể hoặc không thể hoạt động chính xác như các khóa [chuỗi và bộ dữ liệu hoạt động rõ ràng vì chúng không thay đổi]. Tra cứu một giá trị không có trong chính tả sẽ đưa ra Lỗi Key -- sử dụng "in" để kiểm tra xem khóa có trong chính tả hay sử dụng dict.

Làm cách nào để tạo khóa trong Python?

Để chèn khóa/giá trị mới vào Từ điển, hãy sử dụng dấu ngoặc vuông và toán tử gán . Cùng với đó, phương thức update[] cũng có thể được sử dụng. Hãy nhớ rằng, nếu khóa đã có trong từ điển, giá trị của nó sẽ được cập nhật, nếu không, cặp mới sẽ được chèn vào.

Bạn có thể sử dụng một bộ làm khóa trong Python không?

Sử dụng Tuple làm Khóa trong Python . [Nếu bộ chứa các đối tượng có thể thay đổi, nó không thể được sử dụng làm khóa. ] Do đó, một bộ được sử dụng làm khóa có thể chứa các chuỗi, số và các bộ khác chứa tham chiếu đến các đối tượng bất biến. You can use a tuple as a key if all of the elements contained in the tuple are immutable. [If the tuple contains mutable objects, it cannot be used as a key.] Hence a tuple to be used as a key can contain strings, numbers, and other tuples containing references to immutable objects.

Cái nào trong số này không phù hợp làm khóa từ điển?

Chúng ta có thể sử dụng số nguyên, chuỗi, bộ dữ liệu làm khóa từ điển nhưng không thể sử dụng danh sách làm khóa của nó.

Chủ Đề