Saya tidak begitu mengerti sintaks di balik sorted()
argumen:
key=lambda variable: variable[0]
Bukankah lambda
sewenang - wenang? Mengapa variable
dinyatakan dua kali dalam apa yang tampak seperti dict
?
Saya tidak begitu mengerti sintaks di balik sorted()
argumen:
key=lambda variable: variable[0]
Bukankah lambda
sewenang - wenang? Mengapa variable
dinyatakan dua kali dalam apa yang tampak seperti dict
?
Jawaban:
key
adalah fungsi yang akan dipanggil untuk mengubah item koleksi sebelum mereka dibandingkan. Parameter yang diteruskan ke key
harus berupa sesuatu yang bisa dipanggil.
Penggunaan lambda
menciptakan fungsi anonim (yang dapat dipanggil). Dalam hal sorted
callable hanya membutuhkan satu parameter. Python lambda
cukup sederhana. Ia hanya dapat melakukan dan mengembalikan satu hal dengan sungguh-sungguh.
Sintaksnya lambda
adalah kata yang lambda
diikuti oleh daftar nama parameter kemudian satu blok kode. Daftar parameter dan blok kode digambarkan oleh titik dua. Hal ini mirip dengan konstruksi lain di python juga seperti while
, for
, if
dan sebagainya. Itu semua adalah pernyataan yang biasanya memiliki blok kode. Lambda hanyalah contoh pernyataan dengan blok kode.
Kita dapat membandingkan penggunaan lambda dengan def untuk membuat fungsi.
adder_lambda = lambda parameter1,parameter2: parameter1+parameter2
def adder_regular(parameter1, parameter2): return parameter1+parameter2
lambda hanya memberi kita cara untuk melakukan ini tanpa menetapkan nama. Yang membuatnya bagus untuk digunakan sebagai parameter untuk suatu fungsi.
variable
digunakan dua kali di sini karena di sebelah kiri titik dua itu adalah nama parameter dan di sisi kanan sedang digunakan dalam blok kode untuk menghitung sesuatu.
Saya pikir semua jawaban di sini mencakup inti dari apa fungsi lambda lakukan dalam konteks diurutkan () dengan cukup baik, namun saya masih merasa seperti deskripsi yang mengarah pada pemahaman intuitif yang kurang, jadi inilah dua sen saya.
Demi kelengkapan, saya akan menyatakan yang jelas di depan: sortir () mengembalikan daftar elemen yang diurutkan dan jika kita ingin mengurutkan dengan cara tertentu atau jika kita ingin mengurutkan daftar elemen yang kompleks (misalnya daftar bertingkat atau daftar tupel) kita dapat memanggil argumen kunci.
Bagi saya, pemahaman intuitif dari argumen utama, mengapa harus dipanggil, dan penggunaan lambda sebagai fungsi yang dapat dipanggil (anonim) untuk mencapai hal ini datang dalam dua bagian.
Sintaks Lambda adalah sebagai berikut:
lambda input_variable (s) : enak satu liner
misalnya
In [1]: f00 = lambda x: x/2
In [2]: f00(10)
Out[2]: 5.0
In [3]: (lambda x: x/2)(10)
Out[3]: 5.0
In [4]: (lambda x, y: x / y)(10, 2)
Out[4]: 5.0
In [5]: (lambda: 'amazing lambda')() # func with no args!
Out[5]: 'amazing lambda'
key
argumen adalah bahwa ia harus mengambil dalam set instruksi yang pada dasarnya akan menunjuk fungsi 'diurutkan ()' pada elemen daftar yang harus digunakan untuk mengurutkan berdasarkan. Ketika dikatakan key=
, apa artinya sebenarnya: Ketika saya mengulangi daftar elemen satu per satu (yaitu untuk e dalam daftar), saya akan meneruskan elemen saat ini ke fungsi yang saya berikan dalam argumen utama dan menggunakannya untuk membuat daftar yang diubah yang akan memberitahu saya tentang urutan daftar akhir yang disortir.Saksikan berikut ini:
mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=WhatToSortBy)
Contoh dasar:
sorted(mylist)
[2, 3, 3, 4, 6, 8, 23] # semua angka berurutan dari kecil ke besar.
Contoh 1:
mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=lambda x: x%2==0)
[3, 3, 23, 6, 2, 4, 8] # Apakah hasil yang diurutkan ini masuk akal bagi Anda?
Perhatikan bahwa fungsi lambda saya disortir untuk memeriksa apakah (e) genap atau ganjil sebelum menyortir.
TAPI TUNGGU! Anda mungkin (atau mungkin harus) bertanya-tanya dua hal - pertama, mengapa peluang saya datang sebelum evens saya (karena nilai kunci saya tampaknya memberitahu fungsi saya diurutkan untuk memprioritaskan evens dengan menggunakan operator mod di x%2==0
). Kedua, mengapa acara saya rusak? 2 datang sebelum 6 kan? Dengan menganalisis hasil ini, kita akan belajar sesuatu yang lebih dalam tentang bagaimana argumen 'kunci' yang diurutkan () bekerja, terutama dalam hubungannya dengan fungsi lambda anonim.
Pertama, Anda akan melihat bahwa sementara peluang datang sebelum peristiwa, peristiwa itu sendiri tidak diurutkan. Kenapa ini?? Mari kita baca dokumen :
Fungsi Kunci Dimulai dengan Python 2.4, baik list.sort () dan diurutkan () menambahkan parameter kunci untuk menentukan fungsi yang akan dipanggil pada setiap elemen daftar sebelum membuat perbandingan.
Kita harus melakukan sedikit pembacaan di antara baris-baris di sini, tetapi yang dikatakan di sini adalah bahwa fungsi pengurutan hanya dipanggil sekali, dan jika kita menentukan argumen kunci, maka kita mengurutkan berdasarkan nilai yang ditunjuk oleh fungsi kunci.
Jadi apa yang contoh menggunakan pengembalian modulo? Nilai boolean: True == 1
, False == 0
. Jadi, bagaimana cara menyortir menangani kunci ini? Ini pada dasarnya mengubah daftar asli ke urutan 1 dan 0.
[3,6,3,2,4,8,23] menjadi [0,1,0,1,1,1,0]
Sekarang kita pergi ke suatu tempat. Apa yang Anda dapatkan ketika Anda mengurutkan daftar yang diubah?
[0,0,0,1,1,1,1]
Oke, jadi sekarang kita tahu mengapa peluang muncul sebelum yang jahat. Tetapi pertanyaan selanjutnya adalah: Mengapa 6 masih ada sebelum 2 dalam daftar terakhir saya? Yah itu mudah - ini karena penyortiran hanya terjadi sekali! yaitu 1 itu masih mewakili nilai daftar asli, yang berada di posisi aslinya relatif satu sama lain. Karena penyortiran hanya terjadi satu kali, dan kami tidak memanggil fungsi penyortiran apa pun untuk memesan nilai genap asli dari rendah ke tinggi, nilai-nilai tersebut tetap dalam urutan aslinya relatif terhadap satu sama lain.
Pertanyaan terakhirnya adalah ini: Bagaimana saya berpikir secara konseptual tentang bagaimana urutan nilai boolean saya ditransformasikan kembali ke nilai asli ketika saya mencetak daftar akhir yang diurutkan?
Sorted () adalah metode bawaan yang (fakta menyenangkan) menggunakan algoritma pengurutan hybrid yang disebut Timsortyang menggabungkan aspek semacam penggabungan dan jenis penyisipan. Tampak jelas bagi saya bahwa ketika Anda menyebutnya, ada seorang mekanik yang menyimpan nilai-nilai ini dalam memori dan membundelnya dengan identitas boolean mereka (topeng) yang ditentukan oleh (...!) Fungsi lambda. Urutan ditentukan oleh identitas boolean mereka yang dihitung dari fungsi lambda, tetapi perlu diingat bahwa daftar ini (satu dan nol) tidak sendiri diurutkan berdasarkan nilai aslinya. Oleh karena itu, daftar akhir, sementara diorganisir oleh Odds and Evens, tidak diurutkan berdasarkan sublist (yang dalam hal ini tidak sesuai). Fakta bahwa peluang dipesan adalah karena mereka sudah diurutkan secara kebetulan di daftar asli. Yang bisa diambil dari semua ini adalah bahwa ketika lambda melakukan transformasi itu, urutan asli dari daftar tetap dipertahankan.
Jadi bagaimana semua ini berhubungan kembali dengan pertanyaan awal, dan yang lebih penting, intuisi kita tentang bagaimana kita harus mengimplementasikan sortir () dengan argumen kunci dan lambda?
Fungsi lambda dapat dianggap sebagai pointer yang menunjuk ke nilai-nilai yang perlu kita sortir, apakah itu pointer yang memetakan nilai ke boolean-nya yang ditransformasikan oleh fungsi lambda, atau jika elemen tertentu dalam daftar bersarang, tuple, dikt, dll., sekali lagi ditentukan oleh fungsi lambda.
Mari kita coba dan prediksi apa yang terjadi ketika saya menjalankan kode berikut.
mylist = [(3, 5, 8), (6, 2, 8), ( 2, 9, 4), (6, 8, 5)]
sorted(mylist, key=lambda x: x[1])
sorted
Panggilan saya jelas mengatakan, "Tolong urutkan daftar ini". Argumen kunci menjadikannya sedikit lebih spesifik dengan mengatakan, untuk setiap elemen (x) di daftar saya, kembalikan indeks 1 dari elemen itu, lalu urutkan semua elemen dari daftar asli 'daftar saya' dengan urutan daftar yang diurutkan yang dihitung oleh fungsi lambda. Karena kami memiliki daftar tupel, kami dapat mengembalikan elemen yang diindeks dari tupel itu. Jadi kita dapatkan:
[(6, 2, 8), (3, 5, 8), (6, 8, 5), (2, 9, 4)]
Jalankan kode itu, dan Anda akan menemukan bahwa ini adalah urutannya. Cobalah mengindeks daftar bilangan bulat dan Anda akan menemukan bahwa kodenya rusak.
Ini adalah penjelasan panjang lebar, tapi saya harap ini membantu untuk 'mengurutkan' intuisi Anda pada penggunaan fungsi lambda sebagai argumen utama dalam diurutkan () dan seterusnya.
key
fungsi. Jika Anda mencoba memahami sorted
fungsi, lambda
sintaksisnya baru saja masuk ke cara pemahaman.
lambda
adalah kata kunci Python yang digunakan untuk menghasilkan fungsi anonim .
>>> (lambda x: x+2)(3)
5
3
karena sedang diteruskan ke fungsi. Parens berada di sekitar lambda sehingga ekspresi tidak diuraikan sebagai lambda x: x+2(3)
, yang tidak valid karena 2
bukan fungsi.
Satu lagi contoh fungsi penggunaan diurutkan () dengan key = lambda. Mari kita pertimbangkan Anda memiliki daftar tupel. Di setiap tuple Anda memiliki merek, model, dan berat mobil dan Anda ingin mengurutkan daftar tupel ini berdasarkan merek, model, atau berat. Anda bisa melakukannya dengan lambda.
cars = [('citroen', 'xsara', 1100), ('lincoln', 'navigator', 2000), ('bmw', 'x5', 1700)]
print(sorted(cars, key=lambda car: car[0]))
print(sorted(cars, key=lambda car: car[1]))
print(sorted(cars, key=lambda car: car[2]))
Hasil:
[('bmw', 'x5', '1700'), ('citroen', 'xsara', 1100), ('lincoln', 'navigator', 2000)]
[('lincoln', 'navigator', 2000), ('bmw', 'x5', '1700'), ('citroen', 'xsara', 1100)]
[('citroen', 'xsara', 1100), ('bmw', 'x5', 1700), ('lincoln', 'navigator', 2000)]
Karena penggunaan lambda diminta dalam konteks sorted()
, lihat juga https://wiki.python.org/moin/HowTo/Sorting/#Key_Functions
Sekadar pengulangan, tombol (Opsional. Fungsi yang dieksekusi untuk memutuskan urutan. Default tidak ada) dalam fungsi yang diurutkan mengharapkan fungsi dan Anda menggunakan lambda.
Untuk mendefinisikan lambda, Anda menentukan properti objek yang ingin Anda urutkan dan fungsi diurutkan built-in python akan secara otomatis mengurusnya.
Jika Anda ingin mengurutkan berdasarkan beberapa properti maka berikan kunci = lambda x: (property1, property2).
Untuk menentukan urutan-oleh, masukkan kebalikan = true sebagai argumen ketiga (Opsional. Boolean. Salah akan mengurutkan naik, Benar akan mengurutkan menurun. Default adalah Salah) dari fungsi yang diurutkan.
Sederhana dan tidak memakan waktu dengan contoh yang relevan dengan pertanyaan yang diajukan. Ikuti contoh ini:
user = [{"name": "Dough", "age": 55},
{"name": "Ben", "age": 44},
{"name": "Citrus", "age": 33},
{"name": "Abdullah", "age":22},
]
print(sorted(user, key=lambda el: el["name"]))
print(sorted(user, key= lambda y: y["age"]))
Lihatlah nama-nama dalam daftar, mereka mulai dengan D, B, C dan A. Dan jika Anda perhatikan usia, mereka adalah 55, 44, 33 dan 22. Kode cetak pertama
print(sorted(user, key=lambda el: el["name"]))
Hasil ke:
[{'name': 'Abdullah', 'age': 22},
{'name': 'Ben', 'age': 44},
{'name': 'Citrus', 'age': 33},
{'name': 'Dough', 'age': 55}]
mengurutkan nama, karena dengan key = lambda el: el ["name"] kita menyortir nama dan nama kembali dalam urutan abjad.
Kode cetak kedua
print(sorted(user, key= lambda y: y["age"]))
Hasil:
[{'name': 'Abdullah', 'age': 22},
{'name': 'Citrus', 'age': 33},
{'name': 'Ben', 'age': 44},
{'name': 'Dough', 'age': 55}]
mengurutkan berdasarkan usia, dan karenanya daftar kembali berdasarkan urutan usia.
Coba kode ini untuk pemahaman yang lebih baik.
def
.