私はOOP経歴から来て、pythonを学ぼうとしています。リストmax
の中で最大のPlayer
を持つtotalScore
型のインスタンスを返すためにラムダ式を使用するplayers
関数を使用しています。
def winner():
w = max(players, key=lambda p: p.totalScore)
関数は、最大Player
を持つタイプtotalScore
のインスタンスを正しく返します。私は以下の3つのことについて混乱しています。
max
関数はどのように機能しますか?それが取っている議論は何ですか?私は文書を見ましたが、理解できませんでした。key
の使用は何ですか?私はそれがsort
関数のコンテキストでも使われていることを知っていますこれらはすべて非常に厄介な概念的な質問ですが、私が言語を理解するのに役立ちます。あなたが説明するための例を挙げることができればそれは役立ちます。ありがとう
lambda
は無名関数です。次のものと同等です。
def func(p):
return p.totalScore
max
は次のようになります。
max(players, key=func)
しかしdef
ステートメントは複合ステートメントであるため、式が必要なところでは使用できません。そのため、lambda
が使用されることがあります。
lambda
は、def
のreturn文に入力したものと同じです。したがって、lambda
内でステートメントを使用することはできません。式だけが許可されます。
max
は何をしますか?
max(a、b、c、... [、key = func]) - > value
単一の反復可能な引数で、その最大の項目を返します。引数が2つ以上の場合は、最大の引数を返します。
だから、それは単に最大のオブジェクトを返します。
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
は最初のインデックスでアイテムを比較します。最初のインデックスが同じ場合は、2番目のインデックスと比較されます。私の例のように、すべての項目は一意の最初のインデックスを持っているので、あなたは答えとしてこれを得るでしょう:
>>> max(lis)
(4, 'e')
しかし、各項目をインデックス1の値で比較したい場合はどうなりますか。シンプル:lambda
を使う:
>>> max(lis, key = lambda x: x[1])
(-1, 'z')
異なる型のオブジェクトを含むイテラブルの項目を比較する:
混合アイテムのリスト:
lis = ['1','100','111','2', 2, 2.57]
Python 2では2つの異なる型の項目を比較することが可能です :
>>> max(lis) # works in Python 2
'2'
>>> max(lis, key=lambda x: int(x)) # compare integer version of each item
'111'
>>> 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'
最大機能はどのように機能しますか?
それはイテラブルの中で "最大"の項目を探します。私はあなたがそれが何であるかを調べることができると思いますが、そうでなければ、それはあなたがループすることができるもの、すなわちリストかストリングです。
Max関数でのキーワードキーの使用は何ですか?ソート機能のコンテキストでも使用されていることを私は知っています
Key
は、max
に、イテラブル内のどのオブジェクトが他のオブジェクトより大きいかを通知するラムダ関数です。あなたが自分で作成したオブジェクトをソートしていて、整数のような明白なものではないとしましょう。
ラムダ式の意味は?それらを読むには?どうやって動くの?
それはもっと大きな質問です。簡単に言うと、ラムダは、受け渡し、他のコードで使用できる関数です。例を挙げましょう。
def sum(a, b, f):
return (f(a) + f(b))
これはa
とb
の2つのオブジェクトと、関数f
を取ります。各オブジェクトに対してf()
を呼び出してから、それらを一緒に追加します。それで、この呼び出しを見てください:
>>> sum(2, 2, lambda a: a * 2)
8
sum()
は2
を取り、それにラムダ式を呼び出します。そのためf(a)
は2 * 2
になり、これは4になります。それから、b
に対してこれを行い、2つを足し合わせます。
それほど単純ではない用語では、ラムダはラムダ計算から来ています。これは、関数を返す関数の概念です。計算を表現するためのとてもクールな数学の概念。あなたは こちら について読むことができ、そして実際にそれを理解することができますこちら 。
ラムダは混乱を招く可能性があるので、これについてもう少し読むのがおそらくより良いです、そして、それがそれらがどれほど有用であるかすぐに明白ではありません。 こちら を確認してください。
非常に単純化されたバージョンの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
max
name__関数は、iterable
name__から最大値を取得するために使用されます。
イテレータはリスト、タプル、辞書オブジェクトなどです。あるいはあなたが提供した例のようにカスタムオブジェクトさえも可能です。
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
name__を関数に渡すことができます。この引数に基づいて、指定された反復子/引数がソートされ、最大値が返されます。
lambda
name__は、擬似関数として機能するpythonキーワードです。したがって、player
name__オブジェクトを渡すと、player.totalScore
が返されます。したがって、関数max
name__に渡されたイテラブルは、与えられたkey
name__オブジェクトのplayer
totalScoreに従ってソートされ、最大のplayer
name__を持つtotalScore
name__を返します。
key
name__引数が指定されていない場合、最大値はデフォルトの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')
によると ドキュメント :
max(iterable [、key])
max(arg1、arg2、* args [、key])
最大の要素を繰り返し可能な、または最大の2つ以上の引数で返します。位置引数が1つ指定されている場合、iterableは空でない反復可能(空でない文字列、Tuple、listなど)でなければなりません。イテラブルの最大の項目が返されます。 2つ以上の位置引数が指定されている場合、最大の位置引数が返されます。
オプションのkey引数は、list.sort()で使用されるような1引数の順序付け関数を指定します。 key引数を指定する場合は、キーワード形式でなければなりません(例えば、max(a、b、c、key = func))。
これが言っているのは、あなたの場合はリスト、この場合はplayers
を提供しているということです。それからmax
関数はリスト内のすべての項目を反復処理し、それらを互いに比較して「最大」を取得します。
想像できるように、player
のような複雑なオブジェクトでは比較のための値を決めるのが難しいので、key
関数を使って各max
の値を決める方法を決めるためにplayer
引数を与えます。この場合、ラムダ関数を使用して、「p
内のplayers
ごとにp.totalscore
を取得し、それを比較のための値として使用します」と言っています。
max
は、最初の引数にiterable
を取る関数に組み込まれています(listやTupleのように)
キーワード引数key
のデフォルト値はNone
ですが、評価する関数を受け入れます。関数に基づいて反復可能と評価されるラッパーと見なします。
この辞書の例を見てください。
d = {'aim':99, 'aid': 45, 'axe': 59, 'big': 9, 'short': 995, 'sin':12, 'sword':1, 'friend':1000, 'artwork':23}
例:
>>> max(d.keys())
'sword'
Kwarg(key
への関数)なしでイテラブルを渡すだけの場合にわかるように、それはkeyの最大値を返しています(アルファベット順)。
例キーの最大値をアルファベット順に見つける代わりに、キーの長さで最大キーを見つける必要があるかもしれません。
>>>max(d.keys(), key=lambda x: len(x))
'artwork'
この例では、ラムダ関数は反復されるキーの長さを返すので、アルファベット順ではなく値を評価しながら、キーの最大長を追跡し、最大長のキーを返します。
例.
>>> max(d.keys(), key=lambda x: d[x])
'friend'
この例では、ラムダ関数は最大値を持つ対応する辞書キーの値を返しています