2009-10-07 31 views
10

Tôi đã dict bằng Python với các phím có dạng sau:Tôi có thể sắp xếp văn bản theo giá trị số của nó bằng Python không?

mydict = {'0'  : 10, 
      '1'  : 23, 
      '2.0' : 321, 
      '2.1' : 3231, 
      '3'  : 3, 
      '4.0.0' : 1, 
      '4.0.1' : 10, 
      '5'  : 11, 
      # ... etc 
      '10' : 32, 
      '11.0' : 3, 
      '11.1' : 243, 
      '12.0' : 3, 
      '12.1.0': 1, 
      '12.1.1': 2, 
      } 

Một số chỉ số không có sub-giá trị, một số có một mức độ sub-giá trị và một số có hai. Nếu tôi chỉ có một cấp phụ, tôi có thể coi tất cả chúng là số và sắp xếp theo số lượng. Cấp phụ thứ hai buộc tôi phải xử lý tất cả chúng dưới dạng chuỗi. Tuy nhiên, nếu tôi sắp xếp chúng như các chuỗi, tôi sẽ có 10 theo sau 120 theo sau 2.

Tôi có thể sắp xếp các chỉ số chính xác như thế nào?

Lưu ý: Điều tôi thực sự muốn làm là in ra dict được sắp xếp theo chỉ mục. Nếu có một cách tốt hơn để làm điều đó hơn phân loại nó bằng cách nào đó đó là tốt với tôi.

+2

Điều này được gọi là "phân loại tự nhiên". Xem http://stackoverflow.com/questions/34518/natural-sorting-algorithm –

Trả lời

18

Bạn có thể sắp xếp các phím theo cách bạn muốn, bằng cách chia chúng thành '.' và sau đó chuyển đổi từng thành phần vào một số nguyên, như thế này:

sorted(mydict.keys(), key=lambda a:map(int,a.split('.'))) 

trả về này:

['0', 
'1', 
'2.0', 
'2.1', 
'3', 
'4.0.0', 
'4.0.1', 
'5', 
'10', 
'11.0', 
'11.1', 
'12.0', 
'12.1.0', 
'12.1.1'] 

Bạn có thể lặp lại trên đó danh sách các phím, và kéo giá trị ra khỏi từ điển của bạn như cần thiết.

Bạn cũng có thể sắp xếp các kết quả của mydict.items(), rất tương tự:

sorted(mydict.items(), key=lambda a:map(int,a[0].split('.'))) 

này cung cấp cho bạn một danh sách sắp xếp của (key, value) cặp, như thế này:

[('0', 10), 
('1', 23), 
('2.0', 321), 
('2.1', 3231), 
('3', 3), 
# ... 
('12.1.1', 2)] 
+0

Và tất nhiên bạn không cần sử dụng lambda, bạn có thể định nghĩa một hàm theo cách thông thường và chuyển tên. – steveha

+0

Nhanh hơn phiên bản so sánh (ít chuyển đổi/cuộc gọi chức năng hơn). – bobince

2

Chức năng phân loại của Python có thể thực hiện chức năng so sánh tùy chỉnh, vì vậy bạn chỉ cần xác định một hàm so sánh các phím theo cách bạn muốn:

def version_cmp(a, b): 
    '''These keys just look like version numbers to me....''' 
    ai = map(int, a.split('.')) 
    bi = map(int, b.split('.')) 
    return cmp(ai, bi) 

for k in sorted(mydict.keys(), version_cmp): 
    print k, mydict[k] 

Mặc dù vậy, tốt nhất bạn nên sử dụng tham số key thành sorted(). Xem câu trả lời của Ian Clelland để biết ví dụ về điều đó.

+1

Tốt hơn là cung cấp chức năng chính như Ian. Hàm chính được gọi một lần cho mỗi phần tử, hàm cmp được gọi là mọi khi sắp xếp so sánh. –

+0

@gnibbler: Vâng, tôi nhận ra rằng sau khi đọc câu trả lời của Ian ... Tôi đã nghĩ về việc xóa câu trả lời của mình, nhưng tôi đoán nó có thể hữu ích cho những người cần một sự so sánh phức tạp hơn mà không thể thực hiện bằng cách truyền một cách đơn giản ' key'. – sth

2

Là phụ lục cho câu trả lời Ian Clelland's, cuộc gọi map() có thể được thay thế bằng danh sách hiểu ... nếu bạn thích kiểu đó. Nó có thể cũng hiệu quả hơn (mặc dù không đáng kể trong trường hợp này tôi nghi ngờ).

sorted(mydict.keys(), key=lambda a: [int(i) for i in a.split('.')])

1

Đối với niềm vui & tính hữu dụng (ví googling ppl, chủ yếu):

f = lambda i: [int(j) if re.match(r"[0-9]+", j) else j for j in re.findall(r"([0-9]+|[^0-9]+)", i)] 
cmpg = lambda x, y: cmp(f(x), f(y)) 

sử dụng như sorted(list, cmp=cmpg). Ngoài ra, regexes có thể được biên dịch trước (hiếm khi cần thiết, trên thực tế, với bộ nhớ đệm của mô-đun). Và, có thể (dễ dàng) đã sửa đổi, ví dụ, để bao gồm các giá trị âm (thêm -? vào num regex, có lẽ) và/hoặc để sử dụng các giá trị float.

Nó có thể không hiệu quả lắm, nhưng ngay cả khi nó khá hữu ích.

Và, uhm, nó cũng có thể được sử dụng làm khóa = cho sắp xếp().

0

Có một HOWTO phân loại tốt trên trang web python: http://wiki.python.org/moin/HowTo/Sorting. Nó làm cho một giới thiệu tốt để phân loại, và thảo luận về các kỹ thuật khác nhau để thích nghi với kết quả phân loại theo nhu cầu của bạn.

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