0
2

More than 3 years have passed since last update.

Pythonでsorted関数やgroupby関数へdefを渡すときの注意点??

Last updated at Posted at 2020-01-23

Pythonを勉強しているのですが、ハマってしまって、1時間ぐらい立ち往生しました。
一応解決したのですが、どうしても腑に落ちなくて、もしこのメカニズムがわかる方がいらっしゃったらご教示いただけると嬉しいと思い、書きます。

以下は、選手名とブロックの組み合わせで、ロサンゼルスとニューヨークの選手を混ぜて、AブロックとBブロックにそれぞれ分けるプログラムです。

groupLeague.py
import itertools
LA = [('Jake', 'B'), ('Elwood', 'A')]
NY = [('James', 'A'), ('Carry', 'B'), ('Steven', 'B')]
data = itertools.chain(LA, NY)

def getSortKey(item):
    return item[1]

grp = itertools.groupby(sorted(data, key=getSortKey(data), getSortKey(data))

しかし、これを実行すると、
TypeError: 'itertools.chain' object is not subscriptable
とエラーで弾かれてしまいます。

さっぱりわからず大ハマリしたんですが、別のサンプルプログラムを見て直した所、動作しました。
最後の行の、

grp = itertools.groupby(sorted(data, key=getSortKey(data)), getSortKey(data))

を、

grp = itertools.groupby(sorted(data, key=getSortKey), getSortKey)

と、getSortKeyの引数を除いたところ、正常に動作しました。

とりあえずプログラムは動いたんですが、このメカニズムがさっぱりわかりません。
groupbyの2つ目の引数「key部」としてkey値の他に「keyを取得できる関数」を指定できるというのはわかるのですが、関数を指定する場合、なぜ引数を書かなくて良い(というか引数を書いたらエラー)になるのでしょうか??動作を確認する限りでは、第一引数の「iterable部」(sorted~)が自動的に引数として扱われていると思うのですが、ドキュメントにはそれらしい記述は何もありませんでした。

【参考】
Pythonドキュメント itertools --- 効率的なループ実行のためのイテレータ生成関数

sorted関数も同様です。key=getSortkeyの部分で、引数は自動的に第一引数のdataを取っているように見えるのですが、そのメカニズムがわかりません(ドキュメントにもやっぱり記載はありませんでした)。

【参考】
Pythonドキュメント 組み込み関数 sorted

これ、引数を取らないで良いのってどういうメカニズムなんでしょうか…??
調べてみたけどどうしてもわかりませんでした。
多分初歩的な質問だと思うので大変恐縮ですが、ご存じの方はご教示いただけますと大変助かります。

この手のトリッキーな仕様って、どうやって対処したら良いんだろう…。

0
2
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2