2013-07-16 38 views
13

Tôi đang cố gắng lặp qua một từ điển mà tôi đã xác định theo thứ tự cụ thể, nhưng nó luôn lặp theo thứ tự khác với thứ tự tôi đã xác định trong mã của tôi. Đây chỉ là một ví dụ cơ bản về những gì tôi đang cố gắng làm. Từ điển tôi đang lặp lại là lớn hơn nhiều, có nhiều phím được đặt tên phức tạp hơn và không theo thứ tự bảng chữ cái/số.Làm thế nào để lặp qua một từ điển Python theo thứ tự được xác định?

level_lookup = \ 
{ 
'PRIORITY_1' : { 'level' : 'BAD', 'value' : '' }, 
'PRIORITY_2' : { 'level' : 'BAD', 'value' : '' }, 
'PRIORITY_3' : { 'level' : 'BAD', 'value' : '' }, 
'PRIORITY_4' : { 'level' : 'BAD', 'value' : '' }, 
'PRIORITY_5' : { 'level' : 'CHECK', 'value' : '' }, 
'PRIORITY_6' : { 'level' : 'CHECK', 'value' : '' }, 
'PRIORITY_7' : { 'level' : 'GOOD', 'value' : '' }, 
'PRIORITY_8' : { 'level' : 'GOOD', 'value' : '' }, 
} 

for priority in level_lookup: 
    if(level_lookup[ priority ][ 'value' ] == 'TRUE'): 
     set_levels += str(priority) + '\n' 

Tôi cần thứ tự mà tôi xác định từ điển sẽ được giữ nguyên trong quá trình lặp lại. Đơn đặt hàng của tôi không phải là chữ cái, do đó sắp xếp theo thứ tự bảng chữ cái sẽ không thực sự hữu ích. Có cách nào để làm điều này không? Tôi đã thử `level_lookup.items(), nhưng điều đó cũng không duy trì được thứ tự của tôi.

+1

Nếu bạn muốn sử dụng một từ điển thông thường theo một thứ tự cụ thể. .. [không] (http://blog.amir.rachum.com/post/54458435089/python-hash-id-and-dictionary-order). Thay vào đó, hãy sử dụng 'OrderedDict'. – KronoS

+5

Từ điển không có đơn đặt hàng.Đó là, các mục phải xuất hiện theo một thứ tự nào đó khi bạn lặp lại, nhưng mọi thứ đều dễ dàng nhất đối với Python và có thể hoặc không giống với thứ tự các mục được đặt vào và có thể thay đổi khi bạn thêm hoặc xóa các mục. Nếu bạn muốn các mục của bạn trong một đơn đặt hàng, hãy sử dụng một vùng chứa duy trì thứ tự của mục, chẳng hạn như 'collections.OrderedDict'. – kindall

Trả lời

9

Bạn nên sử dụng OrderedDict. Nó hoạt động chính xác theo cách bạn muốn, tuy nhiên bạn cần phải xác định theo cách đó, bạn có thể có danh sách các phím theo thứ tự và lặp qua danh sách và truy cập từ điển. Một cái gì đó một dài dòng:

level_lookup_order = ['PRIORITY_1', 'PRIORITY_2', ...] 
for key in level_lookup_order: 
    if key in level_lookup: 
     do_stuff(level_lookup[key]) 

Điều này sẽ là một nỗi đau để duy trì, vì vậy, tôi khuyên bạn chỉ nên sử dụng OrderedDict.

Là tùy chọn cuối cùng, bạn có thể sử dụng 'hằng số'. Giống như,

PRIORITY_1 = 1 
PRIORITY_2 = 2 
... 
lookup_order = {PRIORITY_1: 42, PRIORITY_2: 24, ...} 
+1

OrderedDict thực hiện thủ thuật một cách hoàn hảo. Cảm ơn! – PseudoPsyche

4

Bạn có thể sử dụng collections.OrderedDict. Nếu điều đó không làm việc cho bạn, bạn có thể sắp xếp các phím trước khi bạn lặp qua chúng:

for k in sorted(myDict, lambda k: int(k.rsplit("_",1)[1]): 
    # do stuff 

Lưu ý tuy nhiên, phân loại đặc biệt này tốn không gian tuyến tính và O (nlogn) thời gian. Ngoài ra, nó sử dụng hệ thống đánh số ngẫu nhiên "PRIORITY_N" để sắp xếp, có thể không phải lúc nào cũng hợp lệ

2

Thử;

for priority in sorted(level_lookup.iterkeys()): 

Như Jon đã chỉ ra, keys()iterkeys() là dư thừa ở đây;

for priority in sorted(level_lookup): 
+2

'iterkeys()' vv ... là dự phòng ở đây ... chỉ cần sử dụng 'sắp xếp (level_lookup)' - nó sẽ làm việc cho Python 2 và 3 –

+0

Vì vậy, nó! Cảm ơn! –

+0

Câu trả lời đáng yêu. Bạn không chắc chắn tại sao đây không phải là câu trả lời "Chính xác" được ưu tiên. –

6

Nếu bạn đang sử dụng tốt với việc sử dụng để khóa sắp xếp:

for key in sorted(level_lookup.keys()): 
    ... 

Đó là điều tôi thường làm gì nếu dict được cung cấp cho tôi, và không phải cái gì tôi nhanh chóng (chứ không phải OrderedDict.

0

Tôi nghĩ rằng bạn sẽ khấm khá hơn không sử dụng một cuốn từ điển có chứa có và thấy không có lý do thuyết phục để sử dụng một trong trường hợp này. Một list sẽ lưu trữ các mục theo thứ tự mong muốn:

level_lookup = [ 
    {'level': 'BAD', 'value': '' }, 
    {'level': 'BAD', 'value': '' }, 
    {'level': 'BAD', 'value': '' }, 
    {'level': 'BAD', 'value': '' }, 
    {'level': 'CHECK', 'value': 'TRUE'}, 
    {'level': 'CHECK', 'value': 'TRUE'}, 
    {'level': 'GOOD', 'value': '' }, 
    {'level': 'GOOD', 'value': '' }, 
] 

set_levels = '' 
for level, priority in enumerate(level_lookup, start=1): 
    if priority['value'] == 'TRUE': 
     set_levels += 'PRIORITY_{!s}\n'.format(level) 
print set_levels 

Trong thực tế, bạn có thể viết toàn bộ điều dạng danh sách hiểu:

set_levels = ('\n'.join('PRIORITY_{!s}'.format(level) 
       for level, priority in enumerate(level_lookup, start=1) 
        if priority['value'] == 'TRUE')) 
print set_levels 
+0

Thao tác này sẽ hoạt động, nhưng có các phần mã khác phụ thuộc vào việc tra cứu từ điển dựa trên các phím. Tôi có thể lặp qua một danh sách, nhưng nó sạch hơn để duy trì cách này hơn là để lặp qua một danh sách rất lớn mỗi khi bạn đang tìm kiếm một cái gì đó lên khi chính được biết đến. – PseudoPsyche

Các vấn đề liên quan