Đúng cách để khởi tạo OrderedDict bằng cách sử dụng hàm tạo của nó sao cho nó giữ được thứ tự dữ liệu ban đầu?


124

Cách chính xác để khởi tạo một từ điển có thứ tự (OD) để nó giữ lại thứ tự của dữ liệu ban đầu là gì?

from collections import OrderedDict

# Obviously wrong because regular dict loses order
d = OrderedDict({'b':2, 'a':1}) 

# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b',2), ('a', 1)])

# What about using a list comprehension, will 'd' preserve the order of 'l'
l = ['b', 'a', 'c', 'aa']
d = OrderedDict([(i,i) for i in l])

Câu hỏi:

  • Sẽ OrderedDictgiữ nguyên thứ tự của một danh sách các bộ dữ liệu, hoặc bộ dữ liệu hoặc bộ danh sách hoặc danh sách danh sách, vv được thông qua tại thời điểm khởi tạo (ví dụ thứ 2 & 3 ở trên)?

  • Làm thế nào để đi xác minh nếu OrderedDictthực sự duy trì một trật tự? Vì a dictcó một thứ tự không thể đoán trước, điều gì sẽ xảy ra nếu các vectơ kiểm tra của tôi may mắn có thứ tự ban đầu giống như thứ tự không thể đoán trước của một lệnh? Ví dụ, nếu thay vì d = OrderedDict({'b':2, 'a':1})tôi viết d = OrderedDict({'a':1, 'b':2}), tôi có thể kết luận sai rằng trật tự được bảo tồn. Trong trường hợp này, tôi phát hiện ra rằng a dictđược sắp xếp theo thứ tự abc, nhưng điều đó có thể không phải lúc nào cũng đúng. Cách đáng tin cậy để sử dụng một ví dụ mẫu để xác minh xem cấu trúc dữ liệu có giữ trật tự hay không, không thử các vectơ kiểm tra lặp đi lặp lại cho đến khi phá vỡ?

PS Tôi sẽ chỉ để lại ở đây để tham khảo : "Phương thức của hàm tạo OrderedDict và update () đều chấp nhận các đối số từ khóa, nhưng thứ tự của chúng bị mất vì hàm của Python gọi các đối số từ khóa thông qua ngữ nghĩa thông thường sử dụng một từ điển không có thứ tự thông thường"

PPS: Hy vọng, trong tương lai, OrderedDict sẽ giữ nguyên thứ tự của kwargs (ví dụ 1): http://bugs.python.org/su16991


9
Thật là mỉa mai khi khởi tạo OrderedDict bằng một lệnh (không trống) là điều sai trái ... có thể cho rằng sẽ dẫn đến Cảnh báo vì có thể vi phạm ý định của người dùng.
smci

3
Sau python3.6, OrderDict(b=2, a=1)cũng là một cách thích hợp. Xem PEP 468 .
IvanaGyro

Câu trả lời:


90

OrderedDict sẽ duy trì mọi thứ tự mà nó có quyền truy cập. Cách duy nhất để truyền dữ liệu theo thứ tự cho nó để khởi tạo là truyền một danh sách (hay nói chung hơn là lặp lại) các cặp khóa-giá trị, như trong hai ví dụ cuối cùng của bạn. Như tài liệu bạn liên kết để nói, OrderedDict không có quyền truy cập vào bất kỳ đơn hàng nào khi bạn chuyển các đối số từ khóa hoặc đối số dict, vì bất kỳ đơn hàng nào bị xóa trước khi hàm tạo OrderedDict nhìn thấy nó.

Lưu ý rằng việc sử dụng một danh sách hiểu trong ví dụ trước của bạn sẽ không thay đổi bất cứ điều gì. Không có sự khác biệt giữa OrderedDict([(i,i) for i in l])OrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c'), ('aa', 'aa')]). Việc hiểu danh sách được đánh giá và tạo danh sách và nó được thông qua; OrderedDict không biết gì về cách nó được tạo ra.


74
# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b', 2), ('a', 1)])

Vâng, điều đó sẽ làm việc. Theo định nghĩa, một danh sách luôn được sắp xếp theo cách nó được trình bày. Điều này cũng đúng cho việc hiểu danh sách, danh sách được tạo giống như cách dữ liệu được cung cấp (nghĩa là nguồn từ danh sách sẽ có tính xác định, có nguồn gốc từ một sethoặc dictkhông quá nhiều).

Làm thế nào để đi xác minh nếu OrderedDictthực sự duy trì một trật tự. Vì một lệnh có một thứ tự không thể đoán trước, điều gì xảy ra nếu các vectơ kiểm tra của tôi may mắn có thứ tự ban đầu giống như thứ tự không thể đoán trước của một lệnh? Ví dụ, nếu thay vì d = OrderedDict({'b':2, 'a':1})tôi viết d = OrderedDict({'a':1, 'b':2}), tôi có thể kết luận sai rằng trật tự được bảo tồn. Trong trường hợp này, tôi phát hiện ra rằng a dictlà thứ tự theo thứ tự abc, nhưng điều đó có thể không phải lúc nào cũng đúng. tức là cách đáng tin cậy để sử dụng một ví dụ truy cập để xác minh xem cấu trúc dữ liệu có giữ trật tự hay không khi thử các vectơ kiểm tra lặp đi lặp lại cho đến khi một lần ngắt.

Bạn giữ danh sách nguồn 2-tuple xung quanh để tham khảo và sử dụng dữ liệu đó làm dữ liệu thử nghiệm cho các trường hợp thử nghiệm của bạn khi bạn thực hiện kiểm tra đơn vị. Lặp lại thông qua chúng và đảm bảo trật tự được duy trì.


Về việc xác minh thứ tự: Làm thế nào để tôi chắc chắn rằng 2 tuple của tôi S break phá vỡ trật tự chính tả nếu không thể đoán trước được? Đây là một câu hỏi chung về bất kỳ cấu trúc dữ liệu nào, có lẽ tôi nên tách nó khỏi câu hỏi này.
nhấp vào

1
Bạn không thể xác định phá vỡ một cái gì đó không có tính quyết định trong tự nhiên.
tàu điện ngầm

1
Vì vậy, cách tiếp cận đúng để kiểm tra những điều như vậy là gì? Bạn cứ cố gắng vô thời hạn? Thứ tự là không thể đoán trước đối với các lập trình viên, nhưng vì nó là bản đồ băm, nên nó tuân theo thuật toán 'một số' & một thử nghiệm đúng nên thử chống lại điều đó?
nhấp vào

2
Xem __hash__. Cụ thể về strloại.
tàu điện ngầm

Theo định nghĩa, một danh sách luôn được sắp xếp theo cách nó được trình bày. Đây là một tuyên bố quan trọng đối với tôi. Tôi quyết định chỉ cần sử dụng một danh sách 2 tuple cho cơ bản của mình OrderedDictđể tôi không có chi phí chuyển đổi danh sách thành một danh sách OrderedDict. Tôi chỉ lặp qua các yếu tố như một danh sách thay vì từ điển.
Bobort
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.