fungsi python max menggunakan 'kunci' dan ekspresi lambda

180

Saya berasal dari latar belakang OOP dan mencoba belajar python. Saya menggunakan maxfungsi yang menggunakan ekspresi lambda untuk mengembalikan instance bertipe Playermaksimum di totalScoreantara daftar players.

def winner():
    w = max(players, key=lambda p: p.totalScore)

Fungsi dengan benar mengembalikan instance bertipe Playermaksimum totalScore. Saya bingung tentang tiga hal berikut:

  1. Bagaimana cara maxkerjanya? Apa argumen yang diambilnya? Saya melihat dokumentasi tetapi gagal untuk mengerti.
  2. Apa gunanya kata kunci keydalam fungsi maks? Saya tahu ini juga digunakan dalam konteks sortfungsi
  3. Arti ungkapan lambda? Bagaimana cara membacanya? Bagaimana mereka bekerja?

Ini semua adalah pertanyaan konseptual yang sangat noobish tetapi akan membantu saya memahami bahasa. Akan membantu jika Anda bisa memberikan contoh untuk menjelaskan. Terima kasih

Vijay
sumber
Versi Python yang mana?
charmlessCoin
2
Sudahkah Anda berkonsultasi dengan dokumentasi ?
Inbar Rose
@charmlessCoin python 2.7.5
Vijay
2
@InbarRose Saya memeriksa dokumentasi untuk fungsi maks. Tidak terlalu memahaminya.
Vijay
10
@InbarRose Halaman ini sebenarnya sekarang adalah hasil teratas di Google untuk python max lambdadan mungkin sebenarnya lebih bermanfaat bagi pengguna baru.
Markus

Jawaban:

277

lambda adalah fungsi anonim, itu setara dengan:

def func(p):
   return p.totalScore     

Sekarang maxmenjadi:

max(players, key=func)

Tetapi karena defpernyataan adalah pernyataan majemuk, mereka tidak dapat digunakan di mana ekspresi diperlukan, itulah sebabnya terkadang lambdadigunakan.

Perhatikan bahwa lambdaitu setara dengan apa yang Anda masukkan dalam pernyataan pengembalian a def. Dengan demikian, Anda tidak dapat menggunakan pernyataan di dalam lambda, hanya ekspresi yang diizinkan.


Apa yang maxharus dilakukan

maks (a, b, c, ... [, key = func]) -> nilai

Dengan argumen iterable tunggal, kembalikan item terbesarnya. Dengan dua atau lebih argumen, kembalikan argumen terbesar.

Jadi, itu hanya mengembalikan objek yang terbesar.


Bagaimana cara keykerjanya?

Secara default di Python 2 keymembandingkan item berdasarkan seperangkat aturan berdasarkan jenis objek (misalnya string selalu lebih besar dari integer).

Untuk memodifikasi objek sebelum perbandingan, atau membandingkan berdasarkan atribut / indeks tertentu, Anda harus menggunakan keyargumen.

Contoh 1:

Contoh sederhana, misalkan Anda memiliki daftar angka dalam bentuk string, tetapi Anda ingin membandingkan item tersebut dengan nilai integernya.

>>> lis = ['1', '100', '111', '2']

Di sini maxmembandingkan item menggunakan nilai aslinya (string dibandingkan secara leksikografis sehingga Anda akan mendapatkan '2'sebagai output):

>>> max(lis)
'2'

Untuk membandingkan item dengan menggunakan nilai integer mereka keydengan sederhana lambda:

>>> max(lis, key=lambda x:int(x))  # compare `int` version of each item
'111'

Contoh 2: Menerapkan maxke daftar tupel.

>>> lis = [(1,'a'), (3,'c'), (4,'e'), (-1,'z')]

Secara default maxakan membandingkan item dengan indeks pertama. Jika indeks pertama sama maka akan membandingkan indeks kedua. Seperti dalam contoh saya, semua item memiliki indeks pertama yang unik, jadi Anda akan mendapatkan ini sebagai jawabannya:

>>> max(lis)
(4, 'e')

Tetapi, bagaimana jika Anda ingin membandingkan setiap item dengan nilai pada indeks 1? Sederhana: gunakan lambda:

>>> max(lis, key = lambda x: x[1])
(-1, 'z')

Membandingkan item dalam iterable yang berisi objek dari tipe yang berbeda :

Daftar dengan barang-barang campuran:

lis = ['1','100','111','2', 2, 2.57]

Dalam Python 2 dimungkinkan untuk membandingkan item dari dua jenis :

>>> max(lis)  # works in Python 2
'2'
>>> max(lis, key=lambda x: int(x))  # compare integer version of each item
'111'

Tetapi dalam Python 3 Anda tidak bisa melakukan itu lagi :

>>> lis = ['1', '100', '111', '2', 2, 2.57]
>>> max(lis)
Traceback (most recent call last):
  File "<ipython-input-2-0ce0a02693e4>", line 1, in <module>
    max(lis)
TypeError: unorderable types: int() > str()

Tapi ini berhasil, karena kami membandingkan versi integer dari setiap objek:

>>> max(lis, key=lambda x: int(x))  # or simply `max(lis, key=int)`
'111'
Ashwini Chaudhary
sumber
Saya pikir ini sudah tua, tapi saya punya pertanyaan tentang ini. Saya melihat untuk fungsi lambda, variabel x atau i atau apa pun selalu mewakili nilai pada indeks itu dalam daftar. Apakah iterasi ini dilakukan oleh fungsi maks atau oleh lambda? Apakah fungsi lambda selalu beralih pada nilai yang mungkin? Misalnya: di lengths = map(lambda word: len(word), words)mana words=['It', 'is', 'raining', 'cats', 'and', 'dogs']saya melihat bahwa lambda mengulangi setiap kata dalam daftar. Apakah selalu melakukan ini?
Mo2
1
@ Iterasi Mo2 dilakukan dengan maxtidak lambda( keyarg adalah opsional), dan selama iterasi setiap item diteruskan ke fungsi yang ditentukan keydan nilai yang dikembalikan kemudian digunakan untuk perbandingan.
Ashwini Chaudhary
2
Hanya untuk orang-orang yang datang ke sini dengan googling "parameter kunci maks". max(lis, key=lambda x:int(x))dapat disederhanakan sebagai max(lis, key=int). Python memiliki fungsi bawaan, int (). Anda juga dapat menggunakan fungsi bawaan lainnya sebagai keyargumen. Misalnya Anda bisa mendapatkan string terpanjang dari lis=['a', 'aa', 'aaa']olehmax(lis, key=len)
YOUNG
1
@YOUNG Kita dapat menggunakan fungsi apapun sebagai argumen kunci bukan hanya builtin fungsi, satu-satunya syarat adalah bahwa fungsi harus menerima item berlalu untuk itu dengan max, min, sorteddll benar. Plus saya sebutkan max(lis, key=int)di bagian akhir. :-)
Ashwini Chaudhary
@ Ashwini Chaudhary .. misalkan Jika saya punya daftar seperti [1,2,3,4,5]. di sini semua item berbeda. Saya menggunakan max fungsi yang diberikan (set (daftar saya), kunci = mylist.count) untuk menemukan item yang paling sering. karena dalam hal ini tidak ada elemen yang berulang. itu mengembalikan item terendah. Bisakah kita melakukan sesuatu sehingga mengembalikan nol atau nol dalam kasus seperti itu.
vikrant rana
12

Versi sangat disederhanakan dari max:

def max(items, key=lambda x: x):
    current = item[0]
    for item in items:
        if key(item) > key(current):
            current = item
    return current

Mengenai lambda:

>>> ident = lambda x: x
>>> ident(3)
3
>>> ident(5)
5

>>> times_two = lambda x: 2*x
>>> times_two(2)
4
Markus Unterwaditzer
sumber
10

Bagaimana cara kerja fungsi maks?

Itu mencari item "terbesar" di iterable. Saya akan berasumsi bahwa Anda dapat mencari apa itu, tetapi jika tidak, itu adalah sesuatu yang dapat Anda putar, yaitu daftar atau string.

Apa gunanya kunci kata kunci dalam fungsi maks? Saya tahu ini juga digunakan dalam konteks fungsi sortir

Keyadalah fungsi lambda yang akan memberi tahu maxobjek mana di iterable yang lebih besar dari yang lain. Katakanlah jika Anda menyortir beberapa objek yang Anda buat sendiri, dan bukan sesuatu yang jelas, seperti bilangan bulat.

Arti ungkapan lambda? Bagaimana cara membacanya? Bagaimana mereka bekerja?

Itu semacam pertanyaan yang lebih besar. Secara sederhana, lambda adalah fungsi yang bisa Anda sampaikan , dan minta kode lain menggunakannya. Ambil ini sebagai contoh:

def sum(a, b, f):
    return (f(a) + f(b))

Ini mengambil dua objek, adan b, dan sebuah fungsi f. Ia memanggil f()setiap objek, lalu menambahkannya bersama. Jadi lihatlah panggilan ini:

>>> sum(2, 2, lambda a:  a * 2)
8

sum()mengambil 2, dan memanggil ekspresi lambda di atasnya. Jadi f(a)menjadi 2 * 2, yang menjadi 4. Kemudian melakukan ini untuk b, dan menambahkan keduanya bersama-sama.

Dalam istilah yang tidak begitu sederhana, lambda berasal dari lambda calculus, yang merupakan gagasan tentang fungsi yang mengembalikan fungsi; konsep matematika yang sangat keren untuk mengekspresikan komputasi. Anda dapat membaca tentang itu di sini , dan kemudian benar-benar mengerti hal itu di sini .

Mungkin lebih baik membaca tentang ini sedikit lebih banyak, karena lambdas dapat membingungkan, dan itu tidak segera jelas seberapa berguna mereka. Periksa di sini .

charmlessCoin
sumber
7

maxfungsi digunakan untuk mendapatkan hasil maksimal dari iterable.

Iterator dapat berupa daftar, tupel, objek dict, dll. Atau bahkan objek kustom seperti pada contoh yang Anda berikan.

max(iterable[, key=func]) -> value
max(a, b, c, ...[, key=func]) -> value

With a single iterable argument, return its largest item.
With two or more arguments, return the largest argument.

Jadi, pada key=funcdasarnya memungkinkan kita untuk memberikan argumen opsional keyke fungsi yang atas dasar iterator / argumen yang diberikan diurutkan & maksimum dikembalikan.

lambdaadalah kata kunci python yang bertindak sebagai fungsi semu. Jadi, ketika Anda mengirimkan playerobjek ke sana, itu akan kembali player.totalScore. Dengan demikian, iterable yang diteruskan ke fungsi maxakan mengurutkan sesuai dengan key totalScore dari playerobjek yang diberikan kepadanya & akan mengembalikan playeryang memiliki maksimum totalScore.

Jika tidak ada keyargumen yang diberikan, maksimum dikembalikan sesuai dengan urutan Python default.

Contoh -

max(1, 3, 5, 7)
>>>7
max([1, 3, 5, 7])
>>>7

people = [('Barack', 'Obama'), ('Oprah', 'Winfrey'), ('Mahatma', 'Gandhi')]
max(people, key=lambda x: x[1])
>>>('Oprah', 'Winfrey')
shad0w_wa1k3r
sumber
6

Menurut dokumentasi :

max (iterable [, key])
max (arg1, arg2, * args [, key])
Mengembalikan item terbesar dalam iterable atau yang terbesar dari dua argumen atau lebih.

Jika satu argumen posisi disediakan, iterable harus merupakan iterable yang tidak kosong (seperti string, tuple, atau daftar yang tidak kosong) Item terbesar di iterable dikembalikan. Jika dua atau lebih argumen posisi disediakan, argumen posisi terbesar dikembalikan.

Argumen kunci opsional menetapkan fungsi pemesanan satu argumen seperti yang digunakan untuk list.sort (). Argumen kunci, jika disertakan, harus dalam bentuk kata kunci (misalnya, maks (a, b, c, key = func)).

Apa yang dikatakan adalah bahwa dalam kasus Anda, Anda memberikan daftar, dalam hal ini players. Kemudian maxfungsi akan beralih ke semua item dalam daftar dan membandingkannya satu sama lain untuk mendapatkan "maksimum".

Seperti yang dapat Anda bayangkan, dengan objek yang kompleks seperti playermenentukan nilainya untuk perbandingan itu rumit, jadi Anda diberikan keyargumen untuk menentukan bagaimana maxfungsi akan menentukan nilai masing-masing player. Dalam hal ini, Anda menggunakan fungsi lambda untuk mengatakan "untuk masing-masingp di playersdapatkan p.totalscoredan menggunakannya sebagai nilai untuk perbandingan".

Inbar Rose
sumber
3

max dibangun pada fungsi yang mengambil argumen pertama iterable (seperti daftar atau tuple)

argumen kata kunci keymemiliki nilai default Nonetetapi menerima fungsi untuk mengevaluasi, menganggapnya sebagai pembungkus yang mengevaluasi iterable berdasarkan fungsi

Pertimbangkan contoh kamus ini:

d = {'aim':99, 'aid': 45, 'axe': 59, 'big': 9, 'short': 995, 'sin':12, 'sword':1, 'friend':1000, 'artwork':23}

Ex:

>>> max(d.keys())
'sword'

Seperti yang Anda lihat jika Anda hanya meneruskan iterable tanpa kwarg (fungsi ke key) itu mengembalikan nilai kunci maksimum (berdasarkan abjad)

Ex. Alih-alih menemukan nilai maksimal kunci secara abjad, Anda mungkin perlu menemukan kunci maks dengan panjang kunci:

>>>max(d.keys(), key=lambda x: len(x))
'artwork'

dalam contoh ini fungsi lambda adalah mengembalikan panjang kunci yang akan diiterasi karenanya ketika mengevaluasi nilai alih-alih mempertimbangkan secara alfabetis akan melacak panjang maks kunci dan mengembalikan kunci yang memiliki panjang maks

Ex.

>>> max(d.keys(), key=lambda x: d[x])
'friend'

dalam contoh ini fungsi lambda adalah mengembalikan nilai kunci kamus terkait yang memiliki nilai maksimum

Gahan
sumber