Ánh xạ hai từ điển Python

Tất cả các kiểu dữ liệu phức hợp mà chúng ta đã nghiên cứu chi tiết cho đến nay — chuỗi, danh sách và bộ — đều là các kiểu chuỗi, sử dụng các số nguyên làm chỉ số để truy cập các giá trị chứa bên trong chúng

Từ điển là một loại từ ghép khác. Chúng là loại ánh xạ tích hợp sẵn của Python. Chúng ánh xạ các khóa, có thể là bất kỳ loại bất biến nào, thành các giá trị, có thể là bất kỳ loại nào (không đồng nhất), giống như các thành phần của danh sách hoặc bộ. Trong các ngôn ngữ khác, chúng được gọi là mảng kết hợp vì chúng kết hợp một khóa với một giá trị

Ví dụ, chúng ta sẽ tạo một từ điển để dịch các từ tiếng Anh sang tiếng Tây Ban Nha. Đối với từ điển này, các phím là chuỗi

Một cách để tạo từ điển là bắt đầu với từ điển trống và thêm khóa. cặp giá trị. Từ điển rỗng được ký hiệu là {} .

>>> eng2sp = {}
>>> eng2sp["one"] = "uno"
>>> eng2sp["two"] = "dos"

Nhiệm vụ đầu tiên tạo một từ điển có tên eng2sp ; . cặp giá trị vào từ điển. Chúng ta có thể in giá trị hiện tại của từ điển theo cách thông thường.

>>> print(eng2sp)
{"two": "dos", "one": "uno"}

Chìa khóa. các cặp giá trị của từ điển được phân tách bằng dấu phẩy. Mỗi cặp chứa một khóa và một giá trị được phân tách bằng dấu hai chấm

băm

Thứ tự của các cặp có thể không như mong đợi. Python sử dụng các thuật toán phức tạp, được thiết kế để truy cập rất nhanh, để xác định vị trí của khóa. các cặp giá trị được lưu trữ trong một từ điển. Đối với mục đích của chúng tôi, chúng tôi có thể coi thứ tự này là không thể đoán trước

Bạn cũng có thể thắc mắc tại sao chúng ta lại sử dụng từ điển khi cùng một khái niệm ánh xạ khóa tới giá trị có thể được triển khai bằng cách sử dụng danh sách các bộ dữ liệu

>>> {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}
{'pears': 217, 'apples': 430, 'oranges': 525, 'bananas': 312}
>>> [('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
[('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]

Lý do là từ điển rất nhanh, được triển khai bằng kỹ thuật gọi là băm, cho phép chúng tôi truy cập giá trị rất nhanh. Ngược lại, danh sách triển khai bộ dữ liệu chậm. Nếu chúng tôi muốn tìm một giá trị được liên kết với một khóa, chúng tôi sẽ phải lặp lại từng bộ dữ liệu, kiểm tra phần tử thứ 0. Điều gì sẽ xảy ra nếu khóa thậm chí không có trong danh sách?

Một cách khác để tạo từ điển là cung cấp danh sách khóa. các cặp giá trị sử dụng cú pháp giống như đầu ra trước đó

>>> eng2sp = {"one": "uno", "two": "dos", "three": "tres"}

Không quan trọng chúng ta viết các cặp theo thứ tự nào. Các giá trị trong từ điển được truy cập bằng khóa, không phải bằng chỉ số, vì vậy không cần quan tâm đến thứ tự

Đây là cách chúng ta sử dụng một khóa để tra cứu giá trị tương ứng

>>> print(eng2sp["two"])
'dos'

Khóa "two" mang lại giá trị "dos".

Danh sách, bộ dữ liệu và chuỗi được gọi là trình tự, bởi vì các phần tử của chúng xuất hiện theo thứ tự. Từ điển là loại từ ghép đầu tiên mà chúng tôi thấy không phải là một chuỗi, vì vậy chúng tôi không thể lập chỉ mục hoặc cắt từ điển

20. 1. Thao tác từ điển¶

Câu lệnh del xóa một khóa. cặp giá trị từ một từ điển. Ví dụ: từ điển sau chứa tên của nhiều loại trái cây và số lượng của từng loại trái cây trong kho.

>>> inventory = {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}
>>> print(inventory)
{'pears': 217, 'apples': 430, 'oranges': 525, 'bananas': 312}

Nếu ai đó mua tất cả các quả lê, chúng tôi có thể xóa mục nhập khỏi từ điển

>>> del inventory["pears"]
>>> print(inventory)
{'apples': 430, 'oranges': 525, 'bananas': 312}

Hoặc nếu chúng tôi mong đợi nhiều lê hơn, chúng tôi có thể thay đổi giá trị được liên kết với lê

>>> inventory["pears"] = 0
>>> print(inventory)
{'pears': 0, 'apples': 430, 'oranges': 525, 'bananas': 312}

Một lô hàng chuối mới đến có thể được xử lý như thế này

________số 8

Chức năng len cũng hoạt động trên từ điển; . cặp giá trị.

>>> len(inventory)
4

20. 2. phương pháp từ điển¶

Từ điển có một số phương pháp tích hợp hữu ích

Phương thức key trả về cái mà Python 3 gọi là chế độ xem các khóa bên dưới của nó. Đối tượng chế độ xem có một số điểm tương đồng với đối tượng range mà chúng ta đã thấy trước đó — đó là một lời hứa lười biếng, cung cấp các phần tử của nó khi phần còn lại cần chúng . Chúng tôi có thể lặp lại chế độ xem hoặc biến chế độ xem thành một danh sách như thế này.

>>> print(eng2sp)
{"two": "dos", "one": "uno"}
0

>>> print(eng2sp)
{"two": "dos", "one": "uno"}
1

Điều này tạo ra đầu ra này

>>> print(eng2sp)
{"two": "dos", "one": "uno"}
2

Việc lặp lại các khóa trong từ điển là điều phổ biến đến mức chúng ta có thể bỏ qua lệnh gọi phương thức key trong for loop — iterating over a dictionary implicitly iterates over its keys:

>>> print(eng2sp)
{"two": "dos", "one": "uno"}
3

>>> print(eng2sp)
{"two": "dos", "one": "uno"}
4

Phương thức giá trị cũng tương tự; .

>>> print(eng2sp)
{"two": "dos", "one": "uno"}
5

Phương thức items cũng trả về một dạng xem hứa hẹn một danh sách các bộ — một bộ cho mỗi khóa. cặp giá trị.

>>> print(eng2sp)
{"two": "dos", "one": "uno"}
6

Các bộ dữ liệu thường hữu ích để nhận cả khóa và giá trị cùng lúc trong khi chúng ta đang lặp

>>> print(eng2sp)
{"two": "dos", "one": "uno"}
3

>>> print(eng2sp)
{"two": "dos", "one": "uno"}
8

Điều này tạo ra

>>> print(eng2sp)
{"two": "dos", "one": "uno"}
9

Cái vàokhông vào operators can test if a key is in the dictionary:

>>> {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}
{'pears': 217, 'apples': 430, 'oranges': 525, 'bananas': 312}
>>> [('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
[('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
0

Phương pháp này có thể rất hữu ích, vì việc tra cứu một khóa không tồn tại trong từ điển sẽ gây ra lỗi thời gian chạy

>>> {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}
{'pears': 217, 'apples': 430, 'oranges': 525, 'bananas': 312}
>>> [('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
[('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
1

20. 3. Bí danh và sao chép¶

Như trong trường hợp danh sách, vì từ điển có thể thay đổi, chúng ta cần lưu ý về bí danh. Bất cứ khi nào hai biến tham chiếu đến cùng một đối tượng, các thay đổi đối với biến này sẽ ảnh hưởng đến biến kia

Nếu chúng tôi muốn sửa đổi từ điển và giữ một bản sao của từ điển gốc, hãy sử dụng phương thức sao chép . Ví dụ: opposites là một từ điển chứa các cặp đối nghĩa.

>>> {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}
{'pears': 217, 'apples': 430, 'oranges': 525, 'bananas': 312}
>>> [('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
[('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
2

bí danhđối nghĩa đề cập đến cùng một đối tượng; . Nếu chúng tôi sửa đổi copy refers to a fresh copy of the same dictionary. If we modify bí danh , thì đối diện cũng bị thay đổi.

>>> {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}
{'pears': 217, 'apples': 430, 'oranges': 525, 'bananas': 312}
>>> [('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
[('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
3

Nếu chúng tôi sửa đổi bản sao , thì đối lập không thay đổi.

>>> {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}
{'pears': 217, 'apples': 430, 'oranges': 525, 'bananas': 312}
>>> [('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
[('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
4

20. 4. Ma trận thưa¶

Trước đây chúng ta đã sử dụng một danh sách các danh sách để biểu diễn một ma trận. Đó là một lựa chọn tốt cho một ma trận có hầu hết các giá trị khác không, nhưng hãy xem xét một ma trận thưa thớt như thế này

Ánh xạ hai từ điển Python

Biểu diễn danh sách chứa rất nhiều số 0

>>> {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}
{'pears': 217, 'apples': 430, 'oranges': 525, 'bananas': 312}
>>> [('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
[('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
5

Một cách khác là sử dụng từ điển. Đối với các khóa, chúng ta có thể sử dụng các bộ chứa số hàng và số cột. Đây là đại diện từ điển của cùng một ma trận

>>> {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}
{'pears': 217, 'apples': 430, 'oranges': 525, 'bananas': 312}
>>> [('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
[('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
6

Chúng tôi chỉ cần ba chìa khóa. cặp giá trị, một cho mỗi phần tử khác không của ma trận. Mỗi khóa là một bộ và mỗi giá trị là một số nguyên

Để truy cập một phần tử của ma trận, chúng ta có thể sử dụng toán tử [] .

>>> {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}
{'pears': 217, 'apples': 430, 'oranges': 525, 'bananas': 312}
>>> [('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
[('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
7

Lưu ý rằng cú pháp biểu diễn từ điển không giống với cú pháp biểu diễn danh sách lồng nhau. Thay vì hai chỉ số nguyên, chúng tôi sử dụng một chỉ số, là một bộ số nguyên

Có một vấn đề. Nếu chúng tôi chỉ định một phần tử bằng 0, chúng tôi sẽ gặp lỗi vì không có mục nhập nào trong từ điển có khóa đó

>>> {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}
{'pears': 217, 'apples': 430, 'oranges': 525, 'bananas': 312}
>>> [('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
[('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
8

Phương thức get giải quyết vấn đề này.

>>> {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}
{'pears': 217, 'apples': 430, 'oranges': 525, 'bananas': 312}
>>> [('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
[('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)]
9

Đối số đầu tiên là khóa; . get should return if the key is not in the dictionary:

>>> eng2sp = {"one": "uno", "two": "dos", "three": "tres"}
0

get chắc chắn cải thiện ngữ nghĩa của việc truy cập ma trận thưa thớt. Xấu hổ về cú pháp.

20. 5. Ghi nhớ¶

Nếu bạn đã chơi với hàm fibo từ chương về đệ quy, bạn có thể nhận thấy rằng đối số bạn cung cấp càng lớn thì . Hơn nữa, thời gian chạy tăng rất nhanh. Trên một trong các máy của chúng tôi, fib(20) kết thúc ngay lập tức, fib(30) takes about a second, and fib(40) takes roughly forever.

Để hiểu lý do tại sao, hãy xem xét biểu đồ cuộc gọi này cho fib với n = 4:

Ánh xạ hai từ điển Python

Biểu đồ lệnh gọi hiển thị một số khung chức năng (các trường hợp khi chức năng được gọi), với các đường kết nối từng khung với khung của các chức năng mà nó gọi. Ở đầu biểu đồ, sợi với n = 4 calls fib with n = 3 and n = 2. In turn, với n = 3 calls fib with n = 2 and n = 1. And so on.

Đếm bao nhiêu lần fib(0)fib(1) are called. This is an inefficient solution to the problem, and it gets far worse as the argument gets bigger.

Một giải pháp tốt là theo dõi các giá trị đã được tính toán bằng cách lưu trữ chúng trong từ điển. Một giá trị được tính toán trước đó được lưu trữ để sử dụng sau này được gọi là bản ghi nhớ. Đây là cách triển khai fib bằng cách sử dụng bản ghi nhớ.

>>> eng2sp = {"one": "uno", "two": "dos", "three": "tres"}
1

>>> eng2sp = {"one": "uno", "two": "dos", "three": "tres"}
2

Từ điển có tên alreadyknown theo dõi các số Fibonacci mà chúng ta đã biết. Chúng tôi bắt đầu chỉ với hai cặp. 0 bản đồ thành 1; .

Bất cứ khi nào fib được gọi, nó sẽ kiểm tra từ điển để xác định xem nó có chứa kết quả không. Nếu nó ở đó, chức năng có thể trở lại ngay lập tức mà không cần thực hiện bất kỳ cuộc gọi đệ quy nào nữa. Nếu không, nó phải tính toán giá trị mới. Giá trị mới được thêm vào từ điển trước khi hàm trả về.

Sử dụng phiên bản fib này, máy của chúng tôi có thể tính toán fib(100) in an eyeblink.

>>> eng2sp = {"one": "uno", "two": "dos", "three": "tres"}
3

20. 6. Đếm chữ cái¶

Trong các bài tập ở Chương 8 (Chuỗi), chúng ta đã viết một hàm đếm số lần xuất hiện của một chữ cái trong một chuỗi. Một dạng tổng quát hơn của bài toán này là lập một bảng tần số của các chữ cái trong chuỗi, tức là mỗi chữ cái xuất hiện bao nhiêu lần

Một bảng tần số như vậy có thể hữu ích cho việc nén tệp văn bản. Vì các chữ cái khác nhau xuất hiện với tần suất khác nhau nên chúng tôi có thể nén tệp bằng cách sử dụng mã ngắn hơn cho các chữ cái phổ biến và mã dài hơn cho các chữ cái ít xuất hiện hơn

Từ điển cung cấp một cách tao nhã để tạo bảng tần số

>>> eng2sp = {"one": "uno", "two": "dos", "three": "tres"}
4

Chúng tôi bắt đầu với một từ điển trống. Đối với mỗi chữ cái trong chuỗi, chúng tôi tìm số đếm hiện tại (có thể bằng 0) và tăng nó. Cuối cùng, từ điển chứa các cặp chữ cái và tần số của chúng

Việc hiển thị bảng tần suất theo thứ tự bảng chữ cái có thể hấp dẫn hơn. Chúng ta có thể làm điều đó với các phương thức itemssort .

>>> eng2sp = {"one": "uno", "two": "dos", "three": "tres"}
5

Lưu ý ở dòng đầu tiên chúng ta phải gọi hàm chuyển đổi kiểu list . Điều đó biến lời hứa mà chúng tôi nhận được từ các mục thành một danh sách, một bước cần thiết trước khi chúng tôi có thể sử dụng của danh sách . method.

20. 7. Bảng chú giải¶

đồ thị cuộc gọi Một đồ thị bao gồm các nút đại diện cho các khung chức năng (hoặc lời gọi) và các cạnh có hướng (các đường có mũi tên) hiển thị khung nào tạo ra các khung khác. từ điển Một bộ sưu tập khóa. cặp giá trị ánh xạ từ khóa sang giá trị. Các khóa có thể là bất kỳ giá trị bất biến nào và giá trị được liên kết có thể thuộc bất kỳ loại nào. giá trị dữ liệu bất biếnMột giá trị dữ liệu không thể sửa đổi. Việc gán cho các phần tử hoặc lát (phần phụ) của các giá trị không thay đổi gây ra lỗi thời gian chạy. keyMột mục dữ liệu được ánh xạ tới một giá trị trong từ điển. Các phím được sử dụng để tra cứu các giá trị trong từ điển. Mỗi khóa phải là duy nhất trong từ điển. Chìa khóa. cặp giá trịMột trong các cặp mục trong từ điển. Các giá trị được tra cứu trong từ điển theo khóa. kiểu ánh xạ Kiểu ánh xạ là kiểu dữ liệu bao gồm tập hợp các khóa và giá trị liên quan. Loại ánh xạ tích hợp duy nhất của Python là từ điển. Từ điển triển khai kiểu dữ liệu trừu tượng mảng kết hợp. ghi nhớLưu trữ tạm thời các giá trị được tính toán trước để tránh lặp lại cùng một phép tính. giá trị dữ liệu có thể thay đổi Một giá trị dữ liệu có thể được sửa đổi. Các loại của tất cả các giá trị có thể thay đổi là các loại hợp chất. Danh sách và từ điển có thể thay đổi;

20. 8. Bài tập¶

  1. Viết chương trình đọc một chuỗi và trả về một bảng các chữ cái trong bảng chữ cái theo thứ tự bảng chữ cái xuất hiện trong chuỗi cùng với số lần xuất hiện của mỗi chữ cái. Trường hợp nên được bỏ qua. Một đầu ra mẫu của chương trình khi người dùng nhập dữ liệu “Đây là Chuỗi có Chữ hoa và chữ thường”, sẽ như thế này

    >>> eng2sp = {"one": "uno", "two": "dos", "three": "tres"}
    
    6

  2. Cung cấp phản hồi của trình thông dịch Python cho từng nội dung sau từ một phiên thông dịch liên tục

    1. >>> eng2sp = {"one": "uno", "two": "dos", "three": "tres"}
      
      7

    2. >>> eng2sp = {"one": "uno", "two": "dos", "three": "tres"}
      
      8

    3. >>> eng2sp = {"one": "uno", "two": "dos", "three": "tres"}
      
      9

    4. >>> print(eng2sp["two"])
      'dos'
      
      0

    5. >>> print(eng2sp["two"])
      'dos'
      
      1

    6. >>> print(eng2sp["two"])
      'dos'
      
      2

    7. >>> print(eng2sp["two"])
      'dos'
      
      3

    Hãy chắc chắn rằng bạn hiểu lý do tại sao bạn nhận được từng kết quả. Sau đó vận dụng kiến ​​thức đã học để điền vào phần thân của hàm dưới đây

    Map() có dùng được trên dictionary Python không?

    Chúng ta có thể sử dụng hàm map() tích hợp sẵn của Python để áp dụng một hàm cho từng mục trong một lần lặp (như danh sách hoặc từ điển) và trả về một trình lặp mới để truy xuất . map() trả về một đối tượng bản đồ (một trình vòng lặp) mà chúng ta có thể sử dụng trong các phần khác của chương trình.

    Làm cách nào để hợp nhất dict trong Python?

    Bằng cách sử dụng phương thức update() trong Python, một danh sách có thể được hợp nhất thành một danh sách khác

    Chức năng nào giúp hợp nhất từ ​​điển d1 và d2?

    Để hợp nhất hai từ điển d1 và d2, hãy tạo deepcopy(d1) là d rồi thực hiện phương pháp cập nhật . Bằng cách này, từ điển gốc sẽ không bị sửa đổi.