2012-05-22 46 views

Trả lời

390

Hãy thử sử dụng từ khóa key với sorted().

sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=lambda x: x[1]) 

key phải là hàm xác định cách truy xuất phần tử so sánh từ cấu trúc dữ liệu của bạn. Trong trường hợp của bạn, nó là phần tử thứ hai của bộ tuple, vì vậy chúng tôi truy cập [1].

Để tối ưu hóa, hãy xem phản hồi của jamylak bằng cách sử dụng itemgetter(1), về cơ bản là phiên bản nhanh hơn của lambda x: x[1].

149
>>> from operator import itemgetter 
>>> data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)] 
>>> sorted(data,key=itemgetter(1)) 
[('abc', 121), ('abc', 148), ('abc', 221), ('abc', 231)] 

IMO sử dụng itemgetter dễ đọc hơn trong trường hợp này so với giải pháp của @cheeken. Nó là cũng nhanh hơn vì hầu như tất cả các tính toán sẽ được thực hiện ở bên c (không có ý định chơi chữ) thay vì thông qua việc sử dụng lambda.

>python -m timeit -s "from operator import itemgetter; data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]" "sorted(data,key=itemgetter(1))" 
1000000 loops, best of 3: 1.22 usec per loop 

>python -m timeit -s "data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]" "sorted(data,key=lambda x: x[1])" 
1000000 loops, best of 3: 1.4 usec per loop 
+10

+1 Tôi đồng ý rằng 'itemgetter()' là một giải pháp tốt hơn.Tuy nhiên, tôi nghĩ rằng một biểu thức lambda sẽ làm cho nó rõ ràng hơn như thế nào 'phím' chức năng. – cheeken

+0

+1 Tuy nhiên, khi tôi chạy thử nghiệm của bạn về tốc độ tôi nhận thấy 'mắt người' mà một trong những nghĩa vụ phải nhanh hơn .. và đo nhanh hơn, thực sự là đáng chú ý chậm hơn. Tôi gãi đầu của tôi về điều này cho một chút, sau đó lấy các mô-đun thời gian chờ python ra chơi và chỉ sử dụng thời gian linux. tức là 'time \' python -c "mã" \ '' sau đó tôi nhận được kết quả 'mắt người' mà bạn đánh vần, cũng như thời gian của đồng hồ sys nhanh hơn. Vẫn không chắc chắn lý do tại sao điều này là, nhưng nó đã được tái sản xuất. Tôi thu thập nó có một cái gì đó để làm với các chi phí tải trong các mô-đun, nhưng vẫn không hoàn toàn làm cho kể từ với tôi, chỉ được nêu ra. –

+1

@JeffSheffield: Lưu ý rằng jamylak đang thực hiện nhập mã cài đặt (ngoài thời gian), không phải mã được thử nghiệm. Điều đó hoàn toàn hợp lý, bởi vì hầu hết các chương trình sẽ cần sắp xếp nhiều hơn một lần, hoặc cần sắp xếp các bộ sưu tập lớn hơn nhiều, nhưng chúng sẽ chỉ thực hiện nhập một lần. (Và đối với những chương trình mà chỉ cần làm một loại nhỏ từng có ... tốt, bạn đang nói về một sự khác biệt dưới một micro giây, vì vậy những người quan tâm một trong hai cách?) – abarnert

13

Từ trăn wiki:

>>> from operator import itemgetter, attrgetter  
>>> sorted(student_tuples, key=itemgetter(2)) 
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]  
>>> sorted(student_objects, key=attrgetter('age')) 
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] 
+0

x = [[[5,3], 1,0345], [[5,6], 5.098], [[5,4], 4,89], [[5,1], 5.97]] Với danh sách như thế này chúng ta có thể sắp xếp bằng cách sử dụng itemgetter() đối với các phần tử trong x [0] [1] không? – nidHi

31

Là một tân đảng viên python, tôi chỉ muốn đề cập rằng nếu dữ liệu đã thực sự trông như thế này:

data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)] 

sau đó sorted() sẽ tự động sắp xếp theo thứ hai phần tử trong tuple, vì các phần tử đầu tiên đều giống hệt nhau.

26

Thêm vào câu trả lời của Cheeken, Đây là cách bạn sắp xếp danh sách các bộ dữ liệu theo mục thứ 2 theo số thứ tự giảm dần.

sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)],key=lambda x: x[1], reverse=True) 
5

Đối với một phương pháp lambda-tránh, lần đầu tiên xác định chức năng của riêng bạn:

def MyFn(a): 
    return a[1] 

thì:

sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=MyFn) 
+2

Lợi ích của việc này là gì? – dromtrund

+4

Một lợi ích sẽ là có một hàm xác định mà bạn có thể sử dụng ở bất cứ đâu mà không cần phải đặt 'lambda x: x [1]' trong nhiều lĩnh vực mã. –

+0

Một lợi ích khác là bạn có thể lập tài liệu/nhận xét tốt hơn nếu đó là một chức năng riêng biệt. – uli42

2

Đối Python 2.7+, công trình này mà làm cho câu trả lời chấp nhận một chút dễ đọc hơn:

sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=lambda (k, val): val) 
0

Thực tế là các giá trị sắp xếp trong OP là các số nguyên không liên quan đến câu hỏi này. Nói cách khác, câu trả lời được chấp nhận sẽ hoạt động nếu giá trị sắp xếp là văn bản. Tôi đưa điều này lên để chỉ ra rằng sắp xếp có thể được sửa đổi trong khi sắp xếp (ví dụ, để tính toán cho trường hợp trên và dưới).

>>> sorted([(121, 'abc'), (231, 'def'), (148, 'ABC'), (221, 'DEF')], key=lambda x: x[1]) 
[(148, 'ABC'), (221, 'DEF'), (121, 'abc'), (231, 'def')] 
>>> sorted([(121, 'abc'), (231, 'def'), (148, 'ABC'), (221, 'DEF')], key=lambda x: str.lower(x[1])) 
[(121, 'abc'), (148, 'ABC'), (231, 'def'), (221, 'DEF')] 
3

Đối với một loại tại chỗ, sử dụng

foo = [(list of tuples)] 
foo.sort(key=lambda x:x[0]) #To sort by first element of the tuple 
+1

Mặc dù câu trả lời này có thể đúng, nhưng tốt hơn là giải thích tại sao câu trả lời này là đúng thay vì chỉ cung cấp mã. Ngoài ra, đây gần như là câu trả lời chính xác của câu trả lời đã tồn tại và đã được chấp nhận cách đây 5 năm, vì vậy điều này không thực sự thêm bất kỳ thứ gì vào trang web. Hãy xem các câu hỏi mới hơn để giúp mọi người! – JNYRanger

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