Tìm hiểu cách cấu trúc dữ liệu từ điển của Python hoạt động như một cách mạnh mẽ và linh hoạt để lưu trữ và truy xuất các đối tượng và dữ liệu trong các ứng dụng của bạn.
Nhà văn cao cấp, Infoworld |InfoWorld |
Mục lục
Cho xem nhiều hơn
Tất cả các ngôn ngữ lập trình đều đi kèm với nhiều cấu trúc dữ liệu, mỗi cấu trúc phù hợp với các loại công việc cụ thể. Trong số các cấu trúc dữ liệu được xây dựng thành Python, từ điển hoặc Python
example_values = {
"integer": 32,
"float": 5.5,
"string": "hello world",
"variable": some_var,
"object": some_obj,
"function_output": some_func[],
"some_list": [1,2,3],
"another_dict": {
"Blade Runner": 1982
}
}
7, nổi bật. Từ điển Python là một cách nhanh chóng, linh hoạt để lưu trữ và truy xuất dữ liệu bằng tên hoặc thậm chí là một loại đối tượng phức tạp hơn, thay vì chỉ là một số chỉ mục.Từ điển Python bao gồm một hoặc nhiều khóa Một đối tượng như một chuỗi hoặc một số nguyên. Mỗi khóa được liên kết với một giá trị, có thể là bất kỳ đối tượng Python nào. Bạn sử dụng một khóa để có được các giá trị liên quan của nó và thời gian tra cứu cho từng cặp khóa/giá trị rất không đổi. Trong các ngôn ngữ khác, loại cấu trúc dữ liệu này đôi khi được gọi là bản đồ băm hoặc mảng kết hợp.
Trong bài viết này, chúng tôi sẽ đi qua những điều cơ bản của từ điển Python, bao gồm cách sử dụng chúng, các kịch bản mà chúng có ý nghĩa, và một số vấn đề và cạm bẫy phổ biến cần biết.
Làm việc với từ điển Python
Hãy bắt đầu với một ví dụ đơn giản về từ điển Python:
movie_years = {
"2001: a space odyssey": 1968,
"Blade Runner": 1982
}
Trong từ điển này, các tên phim là các khóa và năm phát hành là các giá trị. Cấu trúc
example_values = {
"integer": 32,
"float": 5.5,
"string": "hello world",
"variable": some_var,
"object": some_obj,
"function_output": some_func[],
"some_list": [1,2,3],
"another_dict": {
"Blade Runner": 1982
}
}
8 có thể được lặp lại vô thời hạn.Ví dụ chúng ta thấy ở đây được gọi là từ điển theo nghĩa đen, một cấu trúc từ điển được mã hóa cứng vào nguồn của chương trình. Cũng có thể tạo hoặc sửa đổi từ điển theo chương trình, như bạn sẽ thấy sau này.
Chìa khóa trong từ điển
Một khóa từ điển Python có thể là gần như bất kỳ đối tượng Python nào. Tôi nói "gần như" bởi vì đối tượng trong câu hỏi phải có thể băm, có nghĩa là nó phải có giá trị băm [đầu ra của phương pháp
example_values = {
"integer": 32,
"float": 5.5,
"string": "hello world",
"variable": some_var,
"object": some_obj,
"function_output": some_func[],
"some_list": [1,2,3],
"another_dict": {
"Blade Runner": 1982
}
}
9 của nó] không thay đổi trong suốt vòng đời của nó và có thể được so sánh với các đối tượng khác.Bất kỳ đối tượng Python có thể thay đổi nào cũng không có giá trị băm nhất quán trong suốt vòng đời của nó và do đó không thể được sử dụng làm chìa khóa. Chẳng hạn, danh sách không thể là khóa, vì các yếu tố có thể được thêm vào hoặc xóa khỏi danh sách. Tương tự như vậy, bản thân một từ điển không thể là chìa khóa vì lý do tương tự. Nhưng một tuple có thể là một chìa khóa, bởi vì một tuple là bất biến, và do đó có một hàm băm phù hợp trong suốt cuộc đời của nó.
Chuỗi, số [số nguyên và phao giống nhau], các bộ dữ liệu và các đối tượng singleton tích hợp [
new_dict = {}
0, new_dict = {}
1 và new_dict = {}
2] đều là những loại phổ biến để sử dụng làm khóa.Một khóa nhất định là duy nhất cho một từ điển nhất định. Bội số của cùng một khóa không thể. Nếu bạn muốn có một khóa trỏ đến nhiều giá trị, bạn sẽ sử dụng một cấu trúc như danh sách, một tuple hoặc thậm chí từ điển khác làm giá trị. [Thông tin thêm về điều này trong thời gian ngắn.]
Giá trị trong từ điển
Các giá trị trong từ điển có thể là bất kỳ đối tượng Python nào cả. Dưới đây là một số ví dụ về các giá trị:
example_values = {
"integer": 32,
"float": 5.5,
"string": "hello world",
"variable": some_var,
"object": some_obj,
"function_output": some_func[],
"some_list": [1,2,3],
"another_dict": {
"Blade Runner": 1982
}
}
Một lần nữa, để lưu trữ nhiều giá trị trong một khóa, chỉ cần sử dụng một loại container, một danh sách, từ điển hoặc tuple, như giá trị. Trong ví dụ trên, các khóa
new_dict = {}
3 và new_dict = {}
4 giữ danh sách và từ điển tương ứng. Bằng cách này, bạn có thể tạo các cấu trúc lồng nhau ở bất kỳ độ sâu nào cần thiết.Tạo từ điển mới
Bạn có thể tạo một từ điển mới, trống bằng cách khai báo đơn giản:
new_dict = {}
Bạn cũng có thể sử dụng
new_dict = {}
5 tích hợp để tạo một từ điển mới từ một chuỗi các cặp:
new_dict = dict[
[
["integer", 32], ["float", 5.5],
]
]
Một cách khác để xây dựng từ điển là với sự hiểu biết từ điển, trong đó bạn chỉ định các khóa và giá trị từ một chuỗi:
new_dict = {x:x+1 for x in range[3]}
# {0: 1, 1: 2, 2: 3}
Nhận và thiết lập các khóa và giá trị từ điển
Để lấy giá trị từ từ điển, bạn sử dụng cú pháp lập chỉ mục của Python:
example_values["integer"] # yields 32
# Get the year Blade Runner was released
blade_runner_year = movie_years["Blade Runner"]
Nếu bạn có một thùng chứa như một giá trị và bạn muốn truy xuất một giá trị lồng nhau, nghĩa là, một cái gì đó từ bên trong container, bạn có thể truy cập trực tiếp với việc lập chỉ mục [nếu được hỗ trợ] hoặc bằng cách sử dụng một gán kẽ:
example_values["another_dict"]["Blade Runner"] # yields 1982
# or ...
another_dict = example_values["another_dict"]
another_dict["Blade Runner"]
# to access a property of an object in a dictionary:
another_dict["some_obj"].property
Đặt giá trị trong từ điển là đủ đơn giản:
# Set a new movie and year
movie_years["Blade Runner 2049"] = 2017
Sử dụng .get [] để truy xuất các giá trị từ điển một cách an toàn
Nếu bạn cố gắng truy xuất một giá trị bằng cách sử dụng khóa không tồn tại trong một từ điển nhất định, bạn sẽ tăng ngoại lệ
new_dict = {}
6. Một cách phổ biến để xử lý loại truy xuất này là sử dụng khối new_dict = {}
7. Một cách thanh lịch hơn để tìm kiếm một khóa có thể không có phương pháp new_dict = {}
8.Phương pháp
new_dict = {}
8 trên từ điển cố gắng tìm một giá trị liên quan đến một khóa nhất định. Nếu không có giá trị như vậy tồn tại, nó sẽ trả về new_dict = {}
2 hoặc mặc định mà bạn chỉ định. Trong một số tình huống, bạn sẽ muốn nêu rõ một lỗi, nhưng phần lớn thời gian bạn sẽ chỉ muốn cung cấp mặc định lành mạnh.
my_dict = {"a":1}
my_dict["b"] # raises a KeyError exception
my_dict.get["a"] # returns 1
my_dict.get["b"] # returns None
my_dict.get["b", 0] # returns 0, the supplied default
Khi nào nên sử dụng từ điển Python
Sử dụng từ điển Python có ý nghĩa nhất trong các điều kiện sau:
- Bạn muốn lưu trữ các đối tượng và dữ liệu bằng tên, không chỉ là vị trí hoặc số chỉ mục. Nếu bạn muốn lưu trữ các yếu tố để bạn có thể truy xuất chúng theo số chỉ mục của chúng, hãy sử dụng danh sách. Lưu ý rằng bạn có thể sử dụng các số nguyên làm khóa chỉ mục, nhưng điều này không hoàn toàn giống như lưu trữ dữ liệu trong cấu trúc danh sách, được tối ưu hóa cho các hành động như thêm vào cuối danh sách. [Từ điển, như bạn sẽ thấy, không có phần tử "kết thúc" hoặc "bắt đầu" như vậy.] If you want to store elements so that you can retrieve them by their index number, use a list. Note that you can use integers as index keys, but this isn't quite the same as storing data in a list structure, which is optimized for actions like adding to the end of the list. [Dictionaries, as you'll see, have no "end" or "beginning" element as such.]
- Bạn cần tìm dữ liệu và đối tượng nhanh chóng theo tên. Từ điển được tối ưu hóa để tra cứu các khóa hầu như luôn luôn ở trong thời gian liên tục, bất kể kích thước từ điển. Bạn cũng có thể tìm thấy một yếu tố trong danh sách theo vị trí của nó trong thời gian không đổi, nhưng bạn không thể săn lùng một yếu tố cụ thể một cách nhanh chóng, bạn phải lặp lại một danh sách để tìm một điều cụ thể nếu bạn không biết vị trí của nó. Dictionaries are optimized so that lookups for keys are almost always in constant time, regardless of the dictionary size. You can find an element in a list by its position in constant time, too, but you can't hunt for a specific element quickly—you have to iterate through a list to find a specific thing if you don't know its position.
- Thứ tự của các yếu tố không quan trọng bằng sự hiện diện của chúng. Một lần nữa, nếu thứ tự của các phần tử quan trọng hơn là có tồn tại một phần tử nhất định trong bộ sưu tập hay không, hãy sử dụng danh sách. Ngoài ra, như bạn sẽ lưu ý bên dưới, trong khi các từ điển bảo tồn thứ tự mà các yếu tố này được chèn, điều đó không giống như có thể nhanh chóng vào phần tử thứ n. Again, if the ordering of the elements matters more than whether or not a given element exists in the collection, use a list. Also, as you'll note
below, while dictionaries do preserve the order in which these elements are inserted, that's not the same as being able to
1 to the nth element quickly.new_dict = dict[ [ ["integer", 32], ["float", 5.5], ] ]
Gotchas cho các giá trị trong từ điển
Có một vài idiosyncrasies đáng chú ý về cách các giá trị hoạt động trong từ điển.
Đầu tiên, nếu bạn sử dụng một tên biến làm giá trị, những gì được lưu trữ trong khóa đó là giá trị có trong biến tại thời điểm giá trị từ điển được xác định. Đây là một ví dụ:
some_var = 128
example_values = {
"variable": some_var,
"function_output": some_func[]
}
Trong trường hợp này, chúng tôi đặt
new_dict = dict[
[
["integer", 32], ["float", 5.5],
]
]
2 thành số nguyên
new_dict = dict[
[
["integer", 32], ["float", 5.5],
]
]
3 trước khi xác định từ điển. Khóa
new_dict = dict[
[
["integer", 32], ["float", 5.5],
]
]
4 sẽ chứa giá trị
new_dict = dict[
[
["integer", 32], ["float", 5.5],
]
]
3. Nhưng nếu chúng tôi thay đổi
new_dict = dict[
[
["integer", 32], ["float", 5.5],
]
]
2 sau khi từ điển được xác định, nội dung của khóa
new_dict = dict[
[
["integer", 32], ["float", 5.5],
]
]
4 sẽ không thay đổi. [Quy tắc này cũng áp dụng cho danh sách Python và các loại container khác trong Python.]Một quy tắc tương tự áp dụng cho cách đầu ra chức năng hoạt động như các giá trị từ điển. Đối với khóa
new_dict = dict[
[
["integer", 32], ["float", 5.5],
]
]
8, chúng tôi có
new_dict = dict[
[
["integer", 32], ["float", 5.5],
]
]
9. Điều này có nghĩa là khi từ điển được xác định,
new_dict = dict[
[
["integer", 32], ["float", 5.5],
]
]
9 được thực thi và giá trị trả về được sử dụng làm giá trị cho
new_dict = dict[
[
["integer", 32], ["float", 5.5],
]
]
8. Nhưng
new_dict = dict[
[
["integer", 32], ["float", 5.5],
]
]
9 không được thực hiện lại mỗi khi chúng ta truy cập khóa
new_dict = dict[
[
["integer", 32], ["float", 5.5],
]
]
8. Giá trị đó sẽ vẫn là những gì khi nó được tạo ra lần đầu tiên.Nếu chúng tôi muốn chạy lại
new_dict = dict[
[
["integer", 32], ["float", 5.5],
]
]
9 mỗi khi chúng tôi truy cập khóa đó, chúng tôi cần thực hiện một cách tiếp cận khác nhau, một người cũng có những công dụng khác.Gọi các đối tượng chức năng trong từ điển
Các đối tượng chức năng có thể được lưu trữ trong một từ điển là giá trị. Điều này cho phép chúng tôi sử dụng từ điển để thực hiện một trong những lựa chọn các chức năng dựa trên một số khóa chính là một cách phổ biến để mô phỏng chức năng
new_dict = {x:x+1 for x in range[3]}
# {0: 1, 1: 2, 2: 3}
5 được tìm thấy trong các ngôn ngữ khác.Đầu tiên, chúng tôi lưu trữ đối tượng chức năng trong từ điển, sau đó chúng tôi lấy và thực thi nó:
example_values = {
"integer": 32,
"float": 5.5,
"string": "hello world",
"variable": some_var,
"object": some_obj,
"function_output": some_func[],
"some_list": [1,2,3],
"another_dict": {
"Blade Runner": 1982
}
}
0Lưu ý rằng chúng ta cần xác định các chức năng trước, sau đó liệt kê chúng trong từ điển.
Ngoài ra, Python kể từ phiên bản 3.10 có một tính năng gọi là mẫu cấu trúc phù hợp với các câu lệnh
new_dict = {x:x+1 for x in range[3]}
# {0: 1, 1: 2, 2: 3}
5 thông thường. Nhưng trong Python, nó có nghĩa là được sử dụng để phù hợp với các cấu trúc hoặc kết hợp các loại, không chỉ các giá trị đơn lẻ. Nếu bạn muốn sử dụng một giá trị để thực hiện một hành động hoặc chỉ trả về một giá trị khác, hãy sử dụng từ điển.Lặp lại thông qua từ điển
Nếu bạn cần lặp lại thông qua một từ điển để kiểm tra tất cả các khóa hoặc giá trị của nó, có một vài cách khác nhau để làm điều đó. Phổ biến nhất là sử dụng vòng lặp
new_dict = {x:x+1 for x in range[3]}
# {0: 1, 1: 2, 2: 3}
7 trên từ điển, ví dụ:
new_dict = {x:x+1 for x in range[3]}
# {0: 1, 1: 2, 2: 3}
8. Điều này mang lại các khóa trong từ điển, sau đó có thể được sử dụng để truy xuất các giá trị nếu cần:example_values = {
"integer": 32,
"float": 5.5,
"string": "hello world",
"variable": some_var,
"object": some_obj,
"function_output": some_func[],
"some_list": [1,2,3],
"another_dict": {
"Blade Runner": 1982
}
}
1Cuộc gọi này sẽ mang lại
new_dict = {x:x+1 for x in range[3]}
# {0: 1, 1: 2, 2: 3}
9, sau đó
example_values["integer"] # yields 32
# Get the year Blade Runner was released
blade_runner_year = movie_years["Blade Runner"]
0.Nếu chúng ta thay vào đó sử dụng như sau:
example_values = {
"integer": 32,
"float": 5.5,
"string": "hello world",
"variable": some_var,
"object": some_obj,
"function_output": some_func[],
"some_list": [1,2,3],
"another_dict": {
"Blade Runner": 1982
}
}
2Chúng tôi sẽ nhận được
example_values["integer"] # yields 32
# Get the year Blade Runner was released
blade_runner_year = movie_years["Blade Runner"]
1 và
example_values["integer"] # yields 32
# Get the year Blade Runner was released
blade_runner_year = movie_years["Blade Runner"]
2. Trong trường hợp này, chúng tôi đang sử dụng các khóa để có được các giá trị.Nếu chúng ta chỉ muốn các giá trị, chúng ta có thể lặp lại bằng phương pháp
example_values["integer"] # yields 32
# Get the year Blade Runner was released
blade_runner_year = movie_years["Blade Runner"]
3 có sẵn trên từ điển:example_values = {
"integer": 32,
"float": 5.5,
"string": "hello world",
"variable": some_var,
"object": some_obj,
"function_output": some_func[],
"some_list": [1,2,3],
"another_dict": {
"Blade Runner": 1982
}
}
3Cuối cùng, chúng ta có thể thu được cả hai khóa và giá trị với nhau bằng phương thức
example_values["integer"] # yields 32
# Get the year Blade Runner was released
blade_runner_year = movie_years["Blade Runner"]
4:example_values = {
"integer": 32,
"float": 5.5,
"string": "hello world",
"variable": some_var,
"object": some_obj,
"function_output": some_func[],
"some_list": [1,2,3],
"another_dict": {
"Blade Runner": 1982
}
}
4Đặt hàng trong Từ điển Python
Một cái gì đó bạn có thể nhận thấy khi lặp qua từ điển là các khóa thường được trả lại theo thứ tự chúng được chèn.
Đây không phải là trường hợp luôn luôn như vậy. Trước Python 3.6, các mục trong từ điển sẽ không được trả lại theo bất kỳ thứ tự cụ thể nào nếu bạn lặp lại thông qua chúng. Phiên bản 3.6 đã giới thiệu một thuật toán từ điển mới và hiệu quả hơn, trong đó giữ lại thứ tự chèn cho các khóa như một tác dụng phụ thuận tiện.
Trước đây, Python đã cung cấp các bộ sưu tập loại.ordereddict như một cách để xây dựng các từ điển được bảo tồn thứ tự chèn.
example_values["integer"] # yields 32
# Get the year Blade Runner was released
blade_runner_year = movie_years["Blade Runner"]
5 vẫn có sẵn trong thư viện tiêu chuẩn, chủ yếu là do rất nhiều phần mềm hiện có sử dụng nó và cũng vì nó hỗ trợ các phương thức vẫn chưa có sẵn với các dicts thông thường. Chẳng hạn, nó cung cấp
example_values["integer"] # yields 32
# Get the year Blade Runner was released
blade_runner_year = movie_years["Blade Runner"]
6 để trả lại các khóa từ điển theo thứ tự ngược của việc chèn, điều mà từ điển thông thường không làm.Loại bỏ các mục khỏi từ điển
Đôi khi bạn cần loại bỏ một cặp khóa/giá trị hoàn toàn khỏi từ điển. Đối với điều này, hãy sử dụng
example_values["integer"] # yields 32
# Get the year Blade Runner was released
blade_runner_year = movie_years["Blade Runner"]
7 tích hợp:example_values = {
"integer": 32,
"float": 5.5,
"string": "hello world",
"variable": some_var,
"object": some_obj,
"function_output": some_func[],
"some_list": [1,2,3],
"another_dict": {
"Blade Runner": 1982
}
}
5Điều này loại bỏ cặp khóa/giá trị
example_values["integer"] # yields 32
# Get the year Blade Runner was released
blade_runner_year = movie_years["Blade Runner"]
8 khỏi ví dụ của chúng tôi ở đầu bài viết.Lưu ý rằng việc đặt khóa hoặc giá trị thành
new_dict = {}
2 không giống như loại bỏ các phần tử đó khỏi từ điển. Chẳng hạn, lệnh
example_values["another_dict"]["Blade Runner"] # yields 1982
# or ...
another_dict = example_values["another_dict"]
another_dict["Blade Runner"]
# to access a property of an object in a dictionary:
another_dict["some_obj"].property
0 sẽ chỉ đặt giá trị của phím đó thành new_dict = {}
2; Nó sẽ không loại bỏ hoàn toàn khóa.Tìm khóa bằng cách của các giá trị
Một câu hỏi phổ biến với từ điển là liệu có thể tìm thấy chìa khóa hay không bằng cách tìm kiếm một giá trị. Câu trả lời ngắn gọn không phải là ít nhất, không phải không lặp lại các cặp khóa/giá trị để tìm đúng giá trị [và do đó là phím phù hợp để đi với nó].
Nếu bạn thấy mình trong một tình huống mà bạn cần tìm khóa bằng các giá trị của chúng, cũng như các giá trị bằng các khóa của chúng, hãy xem xét giữ hai từ điển, trong đó một trong số chúng có các khóa và giá trị đảo ngược. Tuy nhiên, bạn không thể làm điều này nếu các giá trị bạn lưu trữ không thể băm. Trong một trường hợp như vậy, bạn sẽ phải lặp đi lặp lại thông qua từ điển, hay tốt hơn là tìm ra một giải pháp duyên dáng hơn cho vấn đề mà bạn thực sự đang cố gắng giải quyết.
Từ điển so với bộ
Cuối cùng, Python có một cấu trúc dữ liệu khác, tập hợp, hời hợt giống như một từ điển. Hãy nghĩ về nó như một từ điển chỉ có khóa, nhưng không có giá trị. Cú pháp của nó cũng tương tự như từ điển:
example_values = {
"integer": 32,
"float": 5.5,
"string": "hello world",
"variable": some_var,
"object": some_obj,
"function_output": some_func[],
"some_list": [1,2,3],
"another_dict": {
"Blade Runner": 1982
}
}
6Tuy nhiên, các bộ không phải để lưu trữ thông tin được liên kết với một khóa nhất định. Chúng được sử dụng chủ yếu để lưu trữ các giá trị băm theo cách có thể nhanh chóng được kiểm tra cho sự hiện diện hoặc vắng mặt của chúng. Ngoài ra, các bộ không bảo tồn thứ tự chèn, vì mã chúng sử dụng không giống như mã được sử dụng để tạo từ điển.
Serdar Yegulalp là một nhà văn cao cấp tại Infoworld, tập trung vào học máy, container hóa, devops, hệ sinh thái Python và đánh giá định kỳ.
Bản quyền © 2022 IDG Communications, Inc.