Bộ so sánh tùy chỉnh sắp xếp Python 3

Hàm của bạn không đưa ra câu trả lời nhất quán về cách sắp xếp các số, bởi vì ________ 19 ______ đối với một số giá trị của x và y. Ví dụ: [3 % 4] % 2 == 1[4 % 3] % 2 == 1 cũng. Điều này có nghĩa là 3 > 43 < 4, vô nghĩa. Nếu bạn chuyển đổi nó thành chức năng kiểu cmp như @SystemDown gợi ý, bạn sẽ nhận được kết quả không nhất quán. Ví dụ

>>> sorted[range[3, 6], cmp=greater]
[5, 4, 3]
>>> sorted[range[1, 6], cmp=greater]
[1, 4, 3, 5, 2]

Ở đây 5 nhỏ hơn 4 trong trường hợp này nhưng lớn hơn 4 trong trường hợp khác, sử dụng cùng hàm so sánh

Ngay cả khi chức năng cmp của bạn là tự nhất quán, tôi khuyên bạn không nên sử dụng nó dưới bất kỳ hình thức hoặc cách nào, chẳng hạn như sử dụng hàm cmp_to_key do @zstewart đề xuất, vì chức năng cmp chậm hơn, khó đọc và khó gỡ lỗi hơn so với chức năng khóa tương đương

Khi sử dụng các hàm chính, hàm này chỉ được gọi một lần cho mỗi mục được sắp xếp, vì vậy nếu bạn có một danh sách gồm 1 triệu mục, thì hàm này sẽ được gọi một triệu lần. Sau đó, việc sắp xếp tiến hành và so sánh trung bình các giá trị trả về của hàm khóa n*log[n] lần. Đối với danh sách 1 triệu phần tử, đó là 13. 8 triệu lần

Thay vào đó, nếu bạn sử dụng hàm cmp, thì hàm này sẽ được gọi một lần cho mỗi phép so sánh n*log[n] đó. Một lần nữa, đó là 13. 8 triệu lần nếu danh sách chứa 1 triệu phần tử. Nếu bạn sử dụng cmp_to_key, bạn sẽ nhận thêm chi phí khởi tạo 1 triệu phiên bản của lớp trình trợ giúp

Tôi đã thử nghiệm với danh sách 1 triệu số nguyên ngẫu nhiên bằng cách sử dụng các hàm này, các hàm này thực hiện được điều tương tự

def cmp_func[a, b]:
    if a > b:
        return -1
    elif a < b:
        return 1
    else:
        return 0

def key_func[x]:
    return -x

Sắp xếp với

def cmp_func[a, b]:
    if a > b:
        return -1
    elif a < b:
        return 1
    else:
        return 0

def key_func[x]:
    return -x
1 lấy 1. 35 giây, trong khi sử dụng
def cmp_func[a, b]:
    if a > b:
        return -1
    elif a < b:
        return 1
    else:
        return 0

def key_func[x]:
    return -x
2 cần 2. 43 giây

Vì vậy, để trả lời câu hỏi ngầm của @lzkata, bạn nên xóa đối số cmp để sắp xếp thành 3. x vì

Cách dễ nhất để sắp xếp là dùng hàm sorted[list], hàm này lấy một danh sách và trả về một danh sách mới với các phần tử đó theo thứ tự đã sắp xếp. Danh sách ban đầu không thay đổi

  a = [5, 1, 4, 3]
  print[sorted[a]]  ## [1, 3, 4, 5]
  print[a]  ## [5, 1, 4, 3]

Thông thường nhất là chuyển một danh sách vào hàm sorted[], nhưng trên thực tế, nó có thể lấy bất kỳ loại bộ sưu tập có thể lặp nào làm đầu vào. Danh sách cũ hơn. phương thức sort[] là một phương thức thay thế chi tiết bên dưới. Hàm sorted[] có vẻ dễ sử dụng hơn so với sort[], vì vậy tôi khuyên bạn nên sử dụng sorted[]

Hàm sorted[] có thể được tùy chỉnh thông qua các đối số tùy chọn. Đối số tùy chọn sorted[] Reverse=True, e. g. đã sắp xếp [danh sách, đảo ngược = Đúng], làm cho nó sắp xếp ngược

  strs = ['aa', 'BB', 'zz', 'CC']
  print[sorted[strs]]  ## ['BB', 'CC', 'aa', 'zz'] [case sensitive]
  print[sorted[strs, reverse=True]]   ## ['zz', 'aa', 'CC', 'BB']

Sắp xếp tùy chỉnh với phím=

Để sắp xếp tùy chỉnh phức tạp hơn, sorted[] nhận một "key=" tùy chọn chỉ định chức năng "key" biến đổi từng phần tử trước khi so sánh. Hàm khóa nhận 1 giá trị và trả về 1 giá trị, và giá trị "proxy" được trả về được sử dụng để so sánh trong sắp xếp

Ví dụ: với một danh sách các chuỗi, chỉ định key=len [hàm len[] tích hợp] sắp xếp các chuỗi theo độ dài, từ ngắn nhất đến dài nhất. Sắp xếp gọi len[] cho mỗi chuỗi để lấy danh sách các giá trị độ dài proxy, sau đó sắp xếp theo các giá trị proxy đó

  strs = ['ccc', 'aaaa', 'd', 'bb']
  print[sorted[strs, key=len]]  ## ['d', 'bb', 'ccc', 'aaaa']

Một ví dụ khác, chỉ định "str. Lower" vì chức năng chính là một cách để buộc phân loại xử lý chữ hoa và chữ thường giống nhau

  ## "key" argument specifying str.lower function to use for sorting
  print[sorted[strs, key=str.lower]]  ## ['aa', 'BB', 'CC', 'zz']

Bạn cũng có thể chuyển MyFn của riêng mình làm chức năng chính, như thế này

________số 8_______

Để sắp xếp phức tạp hơn như sắp xếp theo họ rồi theo tên, bạn có thể sử dụng các chức năng như

  from operator import itemgetter

  # [first name, last name, score] tuples
  grade = [['Freddy', 'Frank', 3], ['Anil', 'Frank', 100], ['Anil', 'Wang', 24]]
  sorted[grade, key=itemgetter[1,0]]
  # [['Anil', 'Frank', 100], ['Freddy', 'Frank', 3], ['Anil', 'Wang', 24]]

  sorted[grade, key=itemgetter[0,-1]] # Aha! -1 sorts by last name in reverse order.
  #[['Anil', 'Wang', 24], ['Anil', 'Frank', 100], ['Freddy', 'Frank', 3]]

phương thức sắp xếp[]

Để thay thế cho sorted[], phương thức sort[] trên danh sách sẽ sắp xếp danh sách đó theo thứ tự tăng dần, e. g. danh sách. loại[]. Phương thức sort[] thay đổi danh sách bên dưới và trả về Không, vì vậy hãy sử dụng nó như thế này

  alist.sort[]            ## correct
  alist = blist.sort[]    ## Incorrect. sort[] returns None

Trên đây là một sự hiểu lầm rất phổ biến với sort[] -- nó *không trả về* danh sách đã sắp xếp. Phương thức sort[] phải được gọi trên một danh sách; . Phương thức sort[] có trước hàm sorted[], vì vậy bạn có thể sẽ thấy nó trong mã cũ hơn. Phương thức sort[] không cần tạo danh sách mới nên có thể nhanh hơn một chút trong trường hợp phần tử cần sắp xếp đã có sẵn trong danh sách

bộ dữ liệu

Một bộ là một nhóm các phần tử có kích thước cố định, chẳng hạn như tọa độ [x, y]. Bộ dữ liệu giống như danh sách, ngoại trừ chúng là bất biến và không thay đổi kích thước [bộ dữ liệu không hoàn toàn bất biến vì một trong các phần tử được chứa có thể thay đổi được]. Các bộ dữ liệu đóng một loại vai trò "cấu trúc" trong Python -- một cách thuận tiện để chuyển qua một gói giá trị có kích thước cố định, logic nhỏ. Một hàm cần trả về nhiều giá trị chỉ có thể trả về một bộ giá trị. Ví dụ: nếu tôi muốn có danh sách tọa độ 3 chiều, biểu diễn python tự nhiên sẽ là danh sách các bộ, trong đó mỗi bộ có kích thước 3 chứa một nhóm [x, y, z]

Để tạo một bộ, chỉ cần liệt kê các giá trị trong dấu ngoặc đơn được phân tách bằng dấu phẩy. Tuple "rỗng" chỉ là một cặp dấu ngoặc đơn rỗng. Truy cập các phần tử trong một bộ giống như một danh sách -- len[], [ ], for, in, v.v. tất cả đều hoạt động như nhau

  tuple = [1, 2, 'hi']
  print[len[tuple]]  ## 3
  print[tuple[2]]    ## hi
  tuple[2] = 'bye'  ## NO, tuples cannot be changed
  tuple = [1, 2, 'bye']  ## this works

Để tạo bộ kích thước 1, phần tử đơn lẻ phải được theo sau bởi dấu phẩy

  tuple = ['hi',]   ## size-1 tuple

Đó là một trường hợp buồn cười trong cú pháp, nhưng dấu phẩy là cần thiết để phân biệt bộ dữ liệu với trường hợp thông thường là đặt một biểu thức trong ngoặc đơn. Trong một số trường hợp, bạn có thể bỏ qua dấu ngoặc đơn và Python sẽ thấy từ dấu phẩy mà bạn dự định một bộ

Gán một bộ cho một bộ tên biến có kích thước giống hệt nhau sẽ gán tất cả các giá trị tương ứng. Nếu các bộ dữ liệu không cùng kích thước, nó sẽ báo lỗi. Tính năng này cũng hoạt động cho danh sách

  [x, y, z] = [42, 13, "hike"]
  print[z]  ## hike
  [err_string, err_code] = Foo[]  ## Foo[] returns a length-2 tuple

Danh sách hiểu [tùy chọn]

Khả năng hiểu danh sách là một tính năng nâng cao hơn, phù hợp với một số trường hợp nhưng không cần thiết cho các bài tập và không phải là thứ bạn cần học lúc đầu [tôi. e. bạn có thể bỏ qua phần này]. Hiểu danh sách là một cách nhỏ gọn để viết một biểu thức mở rộng ra toàn bộ danh sách. Giả sử chúng ta có một danh sách nums [1, 2, 3, 4], đây là cách hiểu danh sách để tính danh sách các ô vuông của chúng [1, 4, 9, 16]

  strs = ['aa', 'BB', 'zz', 'CC']
  print[sorted[strs]]  ## ['BB', 'CC', 'aa', 'zz'] [case sensitive]
  print[sorted[strs, reverse=True]]   ## ['zz', 'aa', 'CC', 'BB']
0

Cú pháp là

  strs = ['aa', 'BB', 'zz', 'CC']
  print[sorted[strs]]  ## ['BB', 'CC', 'aa', 'zz'] [case sensitive]
  print[sorted[strs, reverse=True]]   ## ['zz', 'aa', 'CC', 'BB']
3 --
  strs = ['aa', 'BB', 'zz', 'CC']
  print[sorted[strs]]  ## ['BB', 'CC', 'aa', 'zz'] [case sensitive]
  print[sorted[strs, reverse=True]]   ## ['zz', 'aa', 'CC', 'BB']
4 trông giống như một vòng lặp for thông thường, nhưng không có dấu hai chấm [. ]. Expr bên trái của nó được đánh giá một lần cho mỗi phần tử để đưa ra các giá trị cho danh sách mới. Dưới đây là một ví dụ với các chuỗi, trong đó mỗi chuỗi được đổi thành chữ hoa với '. ' nối thêm

  strs = ['aa', 'BB', 'zz', 'CC']
  print[sorted[strs]]  ## ['BB', 'CC', 'aa', 'zz'] [case sensitive]
  print[sorted[strs, reverse=True]]   ## ['zz', 'aa', 'CC', 'BB']
1

Bạn có thể thêm kiểm tra if ở bên phải vòng lặp for để thu hẹp kết quả. Thử nghiệm if được đánh giá cho từng phần tử, chỉ bao gồm các phần tử mà thử nghiệm là đúng

  strs = ['aa', 'BB', 'zz', 'CC']
  print[sorted[strs]]  ## ['BB', 'CC', 'aa', 'zz'] [case sensitive]
  print[sorted[strs, reverse=True]]   ## ['zz', 'aa', 'CC', 'BB']
2

Bài tập. danh sách1. py

Để thực hành tài liệu trong phần này, hãy thử các bài toán sau trong list1. py sử dụng sắp xếp và bộ dữ liệu [trong Bài tập cơ bản]

Chủ Đề