Lựa chọn 1:
key=lambda d:(d['rank']==0, d['rank'])
Phương án 2:
key=lambda d:d['rank'] if d['rank']!=0 else float('inf')
Demo:
"Tôi muốn muốn sắp xếp nó theo các giá trị xếp hạng, thứ tự như sau: 1-2-3-4-0-0-0. " --original tấm áp phích
>>> sorted([0,0,0,1,2,3,4], key=lambda x:(x==0, x))
[1, 2, 3, 4, 0, 0]
>>> sorted([0,0,0,1,2,3,4], key=lambda x:x if x!=0 else float('inf'))
[1, 2, 3, 4, 0, 0]
ý kiến bổ sung:
"Xin bạn có thể giải thích cho tôi (một người mới Python) những gì nó làm tôi có thể thấy rằng đó là một lambda, mà tôi biết là một hàm ẩn danh: bit trong ngoặc là gì?"- OP bình luận
Indexing/lát ký hiệu:
itemgetter('rank')
là điều tương tự như lambda x: x['rank']
là điều tương tự như chức năng:
def getRank(myDict):
return myDict['rank']
Các [...]
được gọi là indexing/ký hiệu slice, xem Explain Python's slice notation - Cũng lưu ý rằng someArray[n]
là ký pháp phổ biến trong nhiều ngôn ngữ lập trình để lập chỉ mục, nhưng có thể không hỗ trợ các lát của biểu mẫu [start:end]
hoặc [start:end:step]
.
key=
vs cmp=
vs so sánh giàu:
Đối với những gì đang xảy ra, có hai cách phổ biến để xác định làm thế nào một thuật toán sắp xếp làm việc: một là với một hàm key
, và thứ hai là với một cmp
chức năng (hiện không được dùng trong python, nhưng linh hoạt hơn rất nhiều). Trong khi chức năng cmp
cho phép bạn tự ý chỉ định cách so sánh hai yếu tố (đầu vào: a
, b
; đầu ra: a<b
hoặc a>b
hoặc a==b
). Mặc dù hợp pháp, nó cung cấp cho chúng tôi không có lợi ích lớn (chúng tôi sẽ phải lặp lại mã một cách vụng về), và một chức năng quan trọng là tự nhiên hơn cho trường hợp của bạn. (Xem "đối tượng so sánh giàu" để biết cách mặc nhiên xác định cmp=
một cách thanh lịch nhưng có thể-quá mức.)
Thực hiện chức năng chủ chốt của bạn:
Đáng tiếc là 0 là một yếu tố của số nguyên và do đó có một thứ tự tự nhiên: 0 là bình thường < 1,2,3 ... Vì vậy, nếu chúng ta muốn áp đặt một quy tắc bổ sung, chúng ta cần phải sắp xếp danh sách ở mức "cao hơn". Chúng tôi thực hiện điều này bằng cách tạo khóa cho một bộ dữ liệu: các bộ dữ liệu được sắp xếp đầu tiên bởi phần tử thứ nhất của chúng, sau đó là phần tử thứ 2 của chúng. Đúng sẽ luôn luôn được đặt hàng sau khi sai, vì vậy tất cả các Trues sẽ được đặt hàng sau khi các Falses; sau đó chúng sẽ sắp xếp như bình thường: (True,1)<(True,2)<(True,3)<...
, (False,1)<(False,2)<...
, (False,*)<(True,*)
. Phương án thay thế (tùy chọn 2), chỉ gán các từ điển hạng-0 một giá trị vô cùng, vì nó được đảm bảo ở trên bất kỳ thứ hạng có thể nào.
More chung thay thế - đối tượng so sánh giàu:
Giải pháp thậm chí tổng quát hơn sẽ được tạo ra một lớp đại diện hồ sơ, sau đó thực hiện __lt__
, __gt__
, __eq__
, __ne__
, __gt__
, __ge__
, và tất cả các khác rich comparison operators, hoặc cách khác chỉ cần thực hiện một trong số đó và __eq__
và sử dụng @functools.total_ordering
decorator. Điều này sẽ khiến đối tượng của lớp đó sử dụng logic tùy chỉnh bất cứ khi nào bạn sử dụng toán tử so sánh (ví dụ: x=Record(name='Joe', rank=12)
y=Record(...)
x<y
); vì chức năng sorted(...)
sử dụng <
và các toán tử so sánh khác theo mặc định trong một loại so sánh, điều này sẽ làm cho hành vi tự động khi sắp xếp và trong các trường hợp khác bạn sử dụng <
và các toán tử so sánh khác. Điều này có thể hoặc có thể không quá nhiều tùy thuộc vào trường hợp sử dụng của bạn.
Cleaner thay thế - không quá tải 0 với ngữ nghĩa:
Tôi tuy nhiên nên chỉ ra rằng đó là một chút nhân tạo để đưa 0s đằng sau 1,2,3,4, vv. Cho dù điều này là hợp lý phụ thuộc vào việc xếp hạng = 0 thực sự có nghĩa là xếp hạng = 0; nếu xếp hạng = 0 thực sự là "thấp hơn" so với xếp hạng = 1 (mà lần lượt thực sự "thấp hơn" so với xếp hạng = 2 ...). Nếu đây thực sự là trường hợp, thì phương pháp của bạn hoàn toàn ổn. Nếu đây không phải là trường hợp, thì bạn có thể xem xét bỏ qua mục nhập 'rank':...
thay vì thiết lập 'rank':0
. Sau đó, bạn có thể sắp xếp theo câu trả lời Lev Levitsky bằng cách sử dụng 'rank' in d
, hoặc bằng cách:
Lựa chọn 1 với chương trình khác nhau:
key=lambda d: (not 'rank' in d, d['rank'])
Lựa chọn 2 với chương trình khác nhau:
key=lambda d: d.get('rank', float('inf'))
sidenote: Dựa vào sự tồn tại của vô hạn trong python gần như là một đường biên hack, làm cho bất kỳ giải pháp nào được đề cập (tuple, đối tượng so sánh), của Lev filter-then-concatenate solution, và thậm chí có thể hơi phức tạp hơn cmp
solution (được đánh máy bởi wilson), tổng quát hơn với các ngôn ngữ khác.
Vui lòng giải thích câu trả lời không chính xác của bạn. =) – ninjagecko
Tùy chọn 1 hoạt động! Cảm ơn. – Richard
Bạn có thể giải thích cho tôi (một người mới sử dụng Python) những gì nó đang làm? Tôi có thể thấy rằng đó là một lambda, mà tôi biết là một chức năng vô danh: những gì các bit trong ngoặc? – Richard