ฟังก์ชั่นหลามสูงสุดโดยใช้ 'สำคัญ' และการแสดงออกแลมบ์ดา


181

ฉันมาจากพื้นหลังของ OOP และพยายามเรียนรู้หลาม ฉันใช้maxฟังก์ชั่นที่ใช้การแสดงออกแลมบ์ดาจะกลับมาเช่นชนิดที่Playerมีสูงสุดในหมู่รายการtotalScoreplayers

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

ฟังก์ชั่นได้อย่างถูกต้องส่งกลับตัวอย่างของประเภทมีสูงสุดPlayer totalScoreฉันสับสนเกี่ยวกับสามสิ่งต่อไปนี้:

  1. วิธีการที่ไม่maxทำงานฟังก์ชั่น? อะไรคือข้อโต้แย้งที่กำลังเกิดขึ้น? ฉันดูเอกสาร แต่ไม่เข้าใจ
  2. คำหลักที่ใช้keyในฟังก์ชั่นสูงสุดคืออะไร? ฉันรู้ว่ามันใช้ในบริบทของsortฟังก์ชั่น
  3. ความหมายของการแสดงออกแลมบ์ดา? อ่านอย่างไร พวกเขาทำงานอย่างไร

ทั้งหมดนี้เป็นคำถามเชิงแนวคิดที่ไม่มีเสียงรบกวนมาก แต่จะช่วยให้ฉันเข้าใจภาษา มันจะช่วยถ้าคุณสามารถยกตัวอย่างเพื่ออธิบาย ขอบคุณ


งูหลามรุ่นไหน?
charmlessCoin

2
คุณอ่านเอกสารแล้วหรือยัง?
Inbar Rose

@charmlessCoin python 2.7.5
วีเจย์

2
@InbarRose ฉันตรวจสอบเอกสารสำหรับฟังก์ชั่นสูงสุด ไม่เข้าใจจริงๆ
วีเจย์

10
@InbarRose หน้านี้จริง ๆ แล้วตอนนี้เป็นผลลัพธ์อันดับต้น ๆ ของ Google python max lambdaและบางทีอาจมีประโยชน์มากกว่าสำหรับผู้ใช้ใหม่
Mark

คำตอบ:


278

lambda เป็นฟังก์ชั่นที่ไม่ระบุชื่อมันเทียบเท่ากับ:

def func(p):
   return p.totalScore     

ตอนนี้maxกลายเป็น:

max(players, key=func)

แต่เนื่องจากdefstatement เป็นstatement แบบผสมจึงไม่สามารถใช้เมื่อต้องการนิพจน์นั่นคือเหตุผลที่บางครั้งlambdaมีการใช้

โปรดทราบว่าเทียบเท่ากับสิ่งที่คุณต้องการใส่ในงบการกลับมาของlambda defดังนั้นคุณไม่สามารถใช้คำสั่งภายใน a lambdaอนุญาตให้ใช้นิพจน์เท่านั้น


อะไรmaxทำอย่างไร

ค่าสูงสุด (a, b, c, ... [, key = func]) -> ค่า

ด้วยอาร์กิวเมนต์ iterable เดียวให้ส่งคืนไอเท็มที่ใหญ่ที่สุด ด้วยอาร์กิวเมนต์สองตัวขึ้นไปส่งคืนอาร์กิวเมนต์ที่ใหญ่ที่สุด

ดังนั้นมันจะคืนค่าวัตถุที่ใหญ่ที่สุด


วิธีการkeyทำงานหรือไม่

ตามค่าเริ่มต้นใน Python 2 จะkeyเปรียบเทียบสินค้าตามชุดของกฎตามประเภทของวัตถุ (เช่นสตริงจะมีค่ามากกว่าจำนวนเต็มเสมอ)

ในการปรับเปลี่ยนวัตถุก่อนทำการเปรียบเทียบหรือเพื่อเปรียบเทียบตามคุณลักษณะ / ดัชนีเฉพาะคุณต้องใช้keyอาร์กิวเมนต์

ตัวอย่างที่ 1:

ตัวอย่างง่ายๆสมมติว่าคุณมีรายการตัวเลขในรูปแบบสตริง แต่คุณต้องการเปรียบเทียบรายการเหล่านั้นด้วยค่าจำนวนเต็ม

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

ที่นี่maxเปรียบเทียบรายการโดยใช้ค่าดั้งเดิมของพวกเขา (สตริงที่มีการเปรียบเทียบพจนานุกรมเพื่อให้คุณได้รับ'2'เป็นเอาท์พุท):

>>> max(lis)
'2'

ในการเปรียบเทียบไอเท็มตามค่าจำนวนเต็มใช้keyกับวิlambda:

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

ตัวอย่างที่ 2: การนำmaxไปใช้กับรายการของสิ่งอันดับ

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

โดยค่าเริ่มต้นmaxจะเปรียบเทียบรายการตามดัชนีแรก หากดัชนีแรกเหมือนกันมันจะเปรียบเทียบดัชนีที่สอง ในตัวอย่างของฉันรายการทั้งหมดมีดัชนีแรกที่ไม่ซ้ำกันดังนั้นคุณจะได้รับสิ่งนี้เป็นคำตอบ:

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

แต่ถ้าคุณต้องการเปรียบเทียบแต่ละรายการด้วยค่าที่ดัชนี 1 ใช้ง่ายlambda:

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

การเปรียบเทียบไอเท็มใน iterable ที่มีออบเจ็กต์ประเภทต่าง ๆ :

รายการที่มีรายการผสม:

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

ใน Python 2 เป็นไปได้ที่จะทำการเปรียบเทียบไอเท็มที่มีสองประเภทที่แตกต่างกัน :

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

แต่ใน Python 3 คุณไม่สามารถทำได้อีกต่อไป :

>>> 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()

แต่ใช้งานได้เนื่องจากเรากำลังเปรียบเทียบรุ่นจำนวนเต็มของแต่ละวัตถุ:

>>> max(lis, key=lambda x: int(x))  # or simply `max(lis, key=int)`
'111'

ฉันคิดว่านี่เก่า แต่ฉันมีคำถามเกี่ยวกับเรื่องนี้ ฉันเห็นฟังก์ชั่นแลมบ์ดาตัวแปร x หรือ i หรืออย่างอื่นแทนค่าในดัชนีนั้นในรายการเสมอ ทำซ้ำโดยฟังก์ชัน max หรือโดย lambda หรือไม่ ฟังก์ชั่นแลมบ์ดาย้ำค่าที่เป็นไปได้เสมอหรือไม่? ตัวอย่างเช่น: lengths = map(lambda word: len(word), words)ที่words=['It', 'is', 'raining', 'cats', 'and', 'dogs']ฉันเห็นว่าแลมบ์ดาวนซ้ำทุกคำในรายการ มันทำสิ่งนี้ตลอดเวลาหรือไม่?
Mo2

1
@ Mo2 Iteration ทำโดยmaxไม่lambda( keyarg เป็นทางเลือก) และในระหว่างการทำซ้ำแต่ละรายการจะถูกส่งผ่านไปยังฟังก์ชันที่ระบุในkeyและจากนั้นจะใช้ค่าที่ส่งคืนเพื่อการเปรียบเทียบ
Ashwini Chaudhary

2
สำหรับคนที่มาที่นี่ด้วย googling "พารามิเตอร์คีย์สูงสุด" สามารถประยุกต์เป็นmax(lis, key=lambda x:int(x)) max(lis, key=int)Python มีฟังก์ชั่นในตัว int () ในทำนองเดียวกันคุณสามารถใช้ฟังก์ชั่นอื่น ๆ ในตัวเป็นkeyอาร์กิวเมนต์ ตัวอย่างเช่นคุณสามารถรับสายอักขระที่ยาวที่สุดได้lis=['a', 'aa', 'aaa']โดยmax(lis, key=len)
YOUNG

1
@YOUNG เราสามารถใช้ฟังก์ชั่นใด ๆ ที่เป็นข้อโต้แย้งที่สำคัญไม่เพียง แต่ฟังก์ชั่นในตัวเงื่อนไขเพียงอย่างเดียวคือฟังก์ชั่นควรจะยอมรับรายการผ่านไปโดยmax, min, sortedฯลฯ ได้อย่างถูกต้อง นอกจากนี้ฉันได้กล่าวถึงmax(lis, key=int)ในตอนท้าย :-)
Ashwini Chaudhary

@Ashwini Chaudhary .. สมมติว่าฉันมีรายการเช่น [1,2,3,4,5] รายการทั้งหมดที่นี่แตกต่างกัน ฉันใช้ฟังก์ชันสูงสุดที่กำหนด (ชุด (รายการ), คีย์ = mylist.count) เพื่อค้นหารายการที่พบบ่อยที่สุด เนื่องจากในกรณีนี้ไม่มีองค์ประกอบที่ซ้ำกัน มันส่งคืนรายการต่ำสุด เราสามารถทำบางอย่างเพื่อให้ผลตอบแทนเป็นศูนย์หรือเป็นโมฆะในกรณีเช่นนี้
vikrant rana

12

เวอร์ชันที่ง่ายมากของmax:

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

เกี่ยวกับแลมบ์ดา:

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

>>> times_two = lambda x: 2*x
>>> times_two(2)
4

10

ฟังก์ชั่น max ทำงานอย่างไร?

มันมองหารายการ "ที่ใหญ่ที่สุด" ใน iterable ฉันจะสมมติว่าคุณสามารถค้นหาสิ่งที่เป็น แต่ถ้าไม่มันเป็นสิ่งที่คุณสามารถวนซ้ำเช่นรายการหรือสตริง

การใช้คีย์เวิร์ดคีย์ในฟังก์ชั่น max คืออะไร? ฉันรู้ว่ามันยังใช้ในบริบทของฟังก์ชั่นการเรียงลำดับ

Keyเป็นฟังก์ชั่นแลมบ์ดาที่จะบอกได้maxว่าวัตถุใดใน iterable ที่ใหญ่กว่าวัตถุอื่น พูดว่าถ้าคุณกำลังเรียงลำดับวัตถุบางอย่างที่คุณสร้างขึ้นมาเองและไม่ใช่สิ่งที่ชัดเจนเช่นจำนวนเต็ม

ความหมายของการแสดงออกแลมบ์ดา? อ่านอย่างไร พวกเขาทำงานอย่างไร

นั่นเป็นคำถามที่ใหญ่กว่า ในแง่ง่ายแลมบ์ดาเป็นฟังก์ชั่นที่คุณสามารถผ่านไปได้และใช้โค้ดอื่น ๆ ยกตัวอย่างเช่น

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

นี้จะใช้เวลาสองวัตถุaและและฟังก์ชั่นb fมันเรียกใช้f()กับแต่ละวัตถุจากนั้นรวมเข้าด้วยกัน ลองดูสายนี้:

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

sum()ใช้เวลา2และเรียกการแสดงออกแลมบ์ดาที่มัน ดังนั้นf(a)กลายเป็น2 * 2ซึ่งกลายเป็น 4 จากนั้นทำเช่นนี้เพื่อbและเพิ่มทั้งสองเข้าด้วยกัน

ในแง่ที่ไม่ง่ายแลมบ์ดามาจากแคลคูลัสแลมบ์ดาซึ่งเป็นแนวคิดของฟังก์ชันที่ส่งคืนฟังก์ชัน แนวคิดทางคณิตศาสตร์ที่ยอดเยี่ยมมากสำหรับแสดงการคำนวณ คุณสามารถอ่านเกี่ยวกับที่นี่แล้วจริงเข้าใจมันนี่

มันน่าจะดีกว่าที่จะอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้อีกหน่อยเนื่องจากลูกแกะอาจสร้างความสับสนและไม่ชัดเจนว่ามีประโยชน์เพียงใด ตรวจสอบที่นี่


7

maxiterableฟังก์ชั่นที่ใช้ในการได้สูงสุดของ

ตัววนซ้ำอาจเป็นรายการ tuples วัตถุ dict ฯลฯ หรือแม้แต่วัตถุที่กำหนดเองตามตัวอย่างที่คุณให้ไว้

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.

ดังนั้นkey=funcโดยพื้นฐานแล้วช่วยให้เราสามารถส่งผ่านอาร์กิวเมนต์ที่เป็นตัวเลือกkeyให้กับฟังก์ชันที่มีการเรียงลำดับตัววนซ้ำ / อาร์กิวเมนต์ที่กำหนดและจำนวนสูงสุดถูกส่งกลับ

lambdaเป็นคำสำคัญหลามที่ทำหน้าที่เป็นฟังก์ชั่นหลอก ดังนั้นเมื่อคุณผ่านวัตถุมันก็จะกลับplayer player.totalScoreดังนั้น iterable ที่ส่งผ่านไปยังฟังก์ชันmaxจะเรียงลำดับตามผลรวมkey หลักของplayerวัตถุที่กำหนดให้ & จะส่งคืนplayerผู้ที่มีค่าสูงสุดtotalScoreที่มีจำนวนมากที่สุด

หากไม่มีการระบุkeyอาร์กิวเมนต์ค่าสูงสุดจะถูกส่งคืนตามการสั่งซื้อ Python เริ่มต้น

ตัวอย่าง -

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')

6

ตามเอกสาร :

max (iterable [, key])
max (arg1, arg2, * args [, key])
คืนค่าไอเท็มที่ใหญ่ที่สุดใน iterable หรืออาร์กิวเมนต์ที่ใหญ่ที่สุดสองข้อขึ้นไป

หากมีการระบุตำแหน่งอาร์กิวเมนต์อย่างใดอย่างหนึ่ง iterable จะต้องเป็น iterable ที่ไม่ว่างเปล่า (เช่นสตริงที่ไม่ว่าง tuple หรือรายการ) ไอเท็มที่ใหญ่ที่สุดใน iterable จะถูกส่งคืน หากมีการระบุตำแหน่งตั้งแต่สองข้อขึ้นไปอาร์กิวเมนต์ตำแหน่งที่ใหญ่ที่สุดจะถูกส่งคืน

อาร์กิวเมนต์ตัวเลือกคีย์ระบุฟังก์ชั่นการสั่งซื้ออาร์กิวเมนต์เดียวเช่นที่ใช้สำหรับ list.sort () อาร์กิวเมนต์คีย์หากระบุจะต้องอยู่ในรูปแบบคำหลัก (ตัวอย่างเช่นสูงสุด (a, b, c, key = func))

สิ่งที่พูดนี้คือในกรณีของคุณคุณให้รายชื่อในกรณีplayersนี้ จากนั้นmaxฟังก์ชั่นจะวนซ้ำรายการทั้งหมดในรายการและเปรียบเทียบกับแต่ละอื่น ๆ เพื่อให้ได้ "สูงสุด"

อย่างที่คุณสามารถจินตนาการได้ด้วยวัตถุที่ซับซ้อนเช่นการplayerกำหนดค่าสำหรับการเปรียบเทียบนั้นมีความยุ่งยากดังนั้นคุณจะได้รับkeyอาร์กิวเมนต์เพื่อพิจารณาว่าmaxฟังก์ชันจะตัดสินมูลค่าของแต่ละสิ่งplayerอย่างไร ในกรณีนี้คุณกำลังใช้ฟังก์ชั่นแลมบ์ดาเพื่อพูดว่า "สำหรับแต่ละรายการpในการplayersรับp.totalscoreและใช้สิ่งนั้นเป็นค่าของเขาสำหรับการเปรียบเทียบ"


3

maxถูกสร้างขึ้นในฟังก์ชั่นซึ่งรับอาร์กิวเมนต์แรกเป็นiterable(เช่น list หรือ tuple)

อาร์กิวเมนต์คำหลัก keyมีค่าเริ่มต้นNoneแต่ยอมรับฟังก์ชั่นในการประเมินพิจารณาเป็น wrapper ซึ่งประเมิน iterable ตามฟังก์ชั่น

พิจารณาพจนานุกรมตัวอย่างนี้:

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

Ex:

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

ในขณะที่คุณสามารถดูว่าคุณผ่าน iterable โดยไม่ต้อง kwarg (ฟังก์ชั่นเพื่อ key ) มันจะคืนค่าสูงสุดของคีย์ (ตัวอักษร)

อดีต แทนที่จะค้นหาค่าสูงสุดของคีย์ตามตัวอักษรคุณอาจต้องค้นหาคีย์สูงสุดตามความยาวของคีย์:

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

ในตัวอย่างนี้ฟังก์ชั่นแลมบ์ดากำลังส่งคืนความยาวของคีย์ซึ่งจะวนซ้ำดังนั้นในขณะที่ประเมินค่าแทนที่จะพิจารณาตามตัวอักษรมันจะติดตามความยาวสูงสุดของคีย์และส่งคืนคีย์ที่มีความยาวสูงสุด

อดีต

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

ในตัวอย่างนี้ฟังก์ชัน lambda กำลังคืนค่าของคีย์พจนานุกรมที่สอดคล้องกันซึ่งมีค่าสูงสุด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.