質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

1589閲覧

sorted()のkeyの働き(特にlambda関数)がいまいち理解できない

gunmed

総合スコア55

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

1クリップ

投稿2019/03/21 05:20

前置き

まず、この問題に直面したのはjupyterでDataFrameに対し、df.applyメソッドの練習を行なっていたときでした。

DataFrameの一部
上記のようなデータ(一部のみスクショ)があり、

df.apply(lambda x: len(x['name']) + len(x['genre']), axis=1).head()

という操作を行い、nameとgenreの文字数を合計するというものでした。
lambda関数を知らなかったので、勉強しました。

a = lambda x: x*2 print(a(5)) >>> 10

というように、引数xとそれに対する式を指定することで、無名の関数を作れると学びました。

そして、そこでsorted()と組み合わせて使うのが代表的な使い方のようだったので、そちらも勉強してみました。

sorted()の第二引数には関数をkeyという名の引数として入れられるようで、それがlambda関数がよく用いられるということだそうです。
そのkeyの使い方がよくわかりません。

#本題
公式には以下のようにkeyについて記述してありました。

key パラメータは単一の引数をとり、ソートに利用される key を返さなければいけません。この制約によりソートを高速に行えます

よくわからなかったのですが、自分の中では、keyに定義した関数をsorted()を行うイレラブルな各要素全てに対して行ってから、sorted()すると解釈しました。

確かに以下のコードでは、リストの各要素を小文字にして、sortしています。

sort_list = sorted("This is a test string from Andrew".split(), key=str.lower) print(sort_list) >>>['a', 'Andrew', 'from', 'is', 'string', 'test', 'This'] sort_list2 = sorted("This is a test string from Andrew".split()) print(sort_list2) >>>['Andrew', 'This', 'a', 'from', 'is', 'string', 'test']

しかし、公式で書かれていた例でlambdaを使用した以下のようなものがありました。

student_tuples = [ ('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10),] sorted(student_tuples, key=lambda student: student[2]) # sort by age >>>[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

たぶん、リストの中のtupleの要素でどれでsortするかをlambda関数は指定してると思うのですが、lambda関数の引数のstudentの働きがよくわかりません。
前置きのようにx = 2のように、studentには具体的な引数を渡していないのに、正常に動いています。

jupyterの方のlambdaと似たような状況なのですが、lambdaの引数になにも渡してないのに、コードがなぜ正常に動くかを教えていただきたいです。また、初心者ゆえ、自分の記述した内容で間違いがあれば訂正していただけると助かります。

mac 10.14.1
使用している教科書 jupyter実践入門、ネット
参考にしたpython公式 https://docs.python.org/ja/3/howto/sorting.html

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

lambdaの引数は仮引数なので、呼び出さなければlambdaが作る関数オブジェクトが返りますし、実引数を渡して呼び出せば関数で計算した結果が返ります。

python

1>>> (lambda x,y: x+y) 2<function <lambda> at 0x7f0204b9cf28> 3>>> (lambda x,y: x+y)(1, 2) 43

sortedの中で内部的に呼ばれるので、コード上は呼び出しがないように見えます。

python

1student_tuples = [ 2 ('john', 'A', 15), 3 ('jane', 'B', 12), 4 ('dave', 'B', 10),] 5 6def f(student): # 呼ばれている証明 7 print(student) 8 return student[2] 9 10sorted(student_tuples, key=f) 11""" => 12('john', 'A', 15) 13('jane', 'B', 12) 14('dave', 'B', 10) 15"""

投稿2019/03/21 06:29

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gunmed

2019/03/21 23:52

回答ありがとうございます。 sortedの内部で呼び出されていることがコードでも確かめられました。 理解が深まりました、ありがとうございました。
guest

0

、自分の中では、keyに定義した関数をsorted()を行うイレラブルな各要素全てに対して行ってから、

それで合っています。
keyの関数は、sortedから、対象要素を1つずつ引数にして呼び出されます。引数は渡していますよ。

参考:

Python

1sorted(student_tuples, key=lambda student: (print("arg =",student),student[2]))

投稿2019/03/21 05:31

編集2019/03/21 05:38
otn

総合スコア84710

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gunmed

2019/03/21 23:50

回答ありがとうございます。 サンプルコードを実際に実行してみて、理解ができ、深まりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問