Câu trả lời:
Không thử nghiệm điều này rất nhiều, nhưng hoạt động trong Python 2.5.2.
>>> d = {"x":2, "h":15, "a":2222}
>>> it = iter(sorted(d.iteritems()))
>>> it.next()
('a', 2222)
>>> it.next()
('h', 15)
>>> it.next()
('x', 2)
>>>
Nếu bạn đã quen làm for key, value in d.iteritems(): ...
thay vì lặp, điều này vẫn sẽ hoạt động với giải pháp ở trên
>>> d = {"x":2, "h":15, "a":2222}
>>> for key, value in sorted(d.iteritems()):
>>> print(key, value)
('a', 2222)
('h', 15)
('x', 2)
>>>
Với Python 3.x, sử dụng d.items()
thay vì d.iteritems()
trả về một trình vòng lặp.
items()
tạo một danh sách và do đó sử dụng bộ nhớ, trong khi iteritems()
về cơ bản không sử dụng bộ nhớ. Những gì để sử dụng chủ yếu phụ thuộc vào kích thước của từ điển. Hơn nữa, công cụ chuyển đổi Python 2 sang Python 3 2to3
tự động ( ) tự động đảm nhiệm việc chuyển đổi từ iteritems()
sang items()
, do đó không cần phải lo lắng về điều này.
collections.OrderedDict
sau đó bạn sắp xếp một lần và nhận các mục theo thứ tự sắp xếp luôn.
iteritems()
không sử dụng bộ nhớ, mọi thứ đều phải được kéo vào bộ nhớ sorted()
, vì vậy không có sự khác biệt giữa việc sử dụng items()
và iteritems()
ở đây là bộ nhớ khôn ngoan.
items()
(trong danh sách được trả về items()
và trong danh sách được sắp xếp) và chỉ một lần với iteritems()
(chỉ trong danh sách được sắp xếp).
Sử dụng sorted()
chức năng:
return sorted(dict.iteritems())
Nếu bạn muốn một trình lặp thực tế trên các kết quả được sắp xếp, vì sorted()
trả về một danh sách, hãy sử dụng:
return iter(sorted(dict.iteritems()))
Các khóa của một dict được lưu trữ trong một hashtable sao cho đó là 'thứ tự tự nhiên' của chúng, tức là psuedo-Random. Bất kỳ thứ tự khác là một khái niệm của người tiêu dùng của dict.
sort () luôn trả về một danh sách, không phải là dict. Nếu bạn truyền cho nó một dict.items () (tạo ra danh sách các bộ dữ liệu), nó sẽ trả về một danh sách các bộ dữ liệu [(k1, v1), (k2, v2), ...] có thể được sử dụng trong một vòng lặp theo một cách rất giống như một dict, nhưng dù sao nó cũng không phải là một dict !
foo = {
'a': 1,
'b': 2,
'c': 3,
}
print foo
>>> {'a': 1, 'c': 3, 'b': 2}
print foo.items()
>>> [('a', 1), ('c', 3), ('b', 2)]
print sorted(foo.items())
>>> [('a', 1), ('b', 2), ('c', 3)]
Sau đây cảm thấy như một lệnh trong một vòng lặp, nhưng không phải, đó là một danh sách các bộ dữ liệu được giải nén vào k, v:
for k,v in sorted(foo.items()):
print k, v
Khá tương đương với:
for k in sorted(foo.keys()):
print k, foo[k]
sorted(foo.keys())
tốt hơn là tương đương sorted(foo)
, vì từ điển trả về các khóa của chúng khi lặp đi lặp lại (với lợi thế là không bị buộc phải tạo foo.keys()
danh sách trung gian, có thể là tùy thuộc vào cách sorted()
triển khai cho các lần lặp).
k in sorted(foo.keys()):
kéo khóa hoặc for k,v in sorted(foo.items()):
trả về một bản sao của cặp danh sách từ điển mà tôi đoánsorted(foo.keys())
Câu trả lời của Greg là đúng. Lưu ý rằng trong Python 3.0 bạn sẽ phải làm
sorted(dict.items())
như iteritems
sẽ biến mất
Bây giờ bạn cũng có thể sử dụng OrderedDict
trong Python 2.7:
>>> from collections import OrderedDict
>>> d = OrderedDict([('first', 1),
... ('second', 2),
... ('third', 3)])
>>> d.items()
[('first', 1), ('second', 2), ('third', 3)]
Tại đây bạn có trang mới cho phiên bản 2.7 và API OrderedDict .
Nói chung, người ta có thể sắp xếp một dict như vậy:
for k in sorted(d):
print k, d[k]
Đối với trường hợp cụ thể trong câu hỏi, có "thả thay thế" cho d.iteritems (), hãy thêm một hàm như:
def sortdict(d, **opts):
# **opts so any currently supported sorted() options can be passed
for k in sorted(d, **opts):
yield k, d[k]
và do đó, dòng kết thúc thay đổi từ
return dict.iteritems()
đến
return sortdict(dict)
hoặc là
return sortdict(dict, reverse = True)
>>> import heapq
>>> d = {"c": 2, "b": 9, "a": 4, "d": 8}
>>> def iter_sorted(d):
keys = list(d)
heapq.heapify(keys) # Transforms to heap in O(N) time
while keys:
k = heapq.heappop(keys) # takes O(log n) time
yield (k, d[k])
>>> i = iter_sorted(d)
>>> for x in i:
print x
('a', 4)
('b', 9)
('c', 2)
('d', 8)
Phương pháp này vẫn có một loại O (N log N), tuy nhiên, sau một heapify tuyến tính ngắn, nó mang lại các mục theo thứ tự sắp xếp, làm cho nó hiệu quả hơn về mặt lý thuyết khi bạn không luôn cần toàn bộ danh sách.
Nếu bạn muốn sắp xếp theo thứ tự các mục được chèn thay vì thứ tự của các khóa, bạn nên xem bộ sưu tập của Python.OrderedDict . (Chỉ Python 3)
đã sắp xếp trả về một danh sách, do đó lỗi của bạn khi bạn cố gắng lặp lại nó, nhưng vì bạn không thể ra lệnh, bạn sẽ phải xử lý một danh sách.
Tôi không biết bối cảnh lớn hơn của mã của bạn là gì, nhưng bạn có thể thử thêm một trình lặp vào danh sách kết quả. như thế này có lẽ?:
return iter(sorted(dict.iteritems()))
tất nhiên bạn sẽ nhận lại các bộ dữ liệu ngay bây giờ vì được sắp xếp đã biến chính tả của bạn thành một danh sách các bộ dữ liệu
ví dụ: nói dict của bạn là: được
{'a':1,'c':3,'b':2}
sắp xếp biến nó thành một danh sách:
[('a',1),('b',2),('c',3)]
vì vậy khi bạn thực sự lặp lại danh sách, bạn sẽ quay lại (trong ví dụ này) một bộ gồm một chuỗi và một số nguyên, nhưng ít nhất bạn sẽ có thể lặp lại nó.
Giả sử bạn đang sử dụng CPython 2.x và có một từ điển lớn mydict, thì việc sử dụng sort (mydict) sẽ bị chậm vì sắp xếp xây dựng một danh sách sắp xếp các khóa của mydict.
Trong trường hợp đó, bạn có thể muốn xem gói orderdict của tôi bao gồm triển khai C sorteddict
trong C. Đặc biệt nếu bạn phải xem qua danh sách các khóa được sắp xếp nhiều lần ở các giai đoạn khác nhau (ví dụ: số phần tử) của thời gian từ điển.
.items()
thay vìiteritems()
: như @Claudiu đã nói, iteritems không hoạt động với Python 3.x, nhưngitems()
có sẵn từ Python 2.6.