読者です 読者をやめる 読者になる 読者になる

Homeの5問目(Min and Max)

py.checkio.org

組み込み関数であるmax()とmin()を自力で実装するという問題ですね。
最低限の実装としては引数のargsをソートして最大もしくは最小を取り出すって感じでどうでしょう。
もう一つの引数であるkeyの扱いは少し悩ましい感じなのですが。
とりあえず、keyの扱いは置いておいて上記の方法で使えそうな関数を調べると、
配列をソートするsorted()って関数を発見。

http://docs.python.jp/2/howto/sorting.html

しかもkeyも普通に使えるという素晴らしさですね。
ということでさっくり、

def min(*args, **kwargs):
    key = kwargs.get("key", None)
    if len(args) > 1:
        result = sorted(args, key=key)[0]
    else :
        result = sorted(args[0], key=key)[0]
    return result

def man(*args, **kwargs):
    key = kwargs.get("key", None)
    if len(args) > 1:
        result = sorted(args, key=key, reverse=True)[0]
    else :
        result = sorted(args[0], key=key, reverse=True)[0]
    return result

でいけてしまいました。
残念なところとしてはargsがイテラブルなのか違うのかの判別方法がなかったので、
argsの長さで調べるという手段しかみつけられなかったことでしょうか。
あとは書き方でJSなんかで使える「?」での分岐(三項演算子っていうんですね)が使えればもう少し綺麗に書けそうなのに、
と思って調べてみると

http://qiita.com/howmuch/items/bf6d21f603d9736fb4a5

という素敵なのがあったので、それを使って書き直しました。

def min(*args, **kwargs):
    key = kwargs.get("key", None)
    result = sorted(args, key=key)[0] if len(args) > 1 else result = sorted(args[0], key=key)[0]
    return result

def man(*args, **kwargs):
    key = kwargs.get("key", None)
    result = sorted(args, key=key, reverse=True)[0] if len(args) > 1 else result = sorted(args[0], key=key, reverse=True)[0]
    return result

 

ちょっと三項演算子のところが冗長的ではありますが、
個人的に許せる範囲だったので一旦終了。
ちなみに高評価回答はkeyの処理を引数内で行ってるのとargsの判別を関数組んでる感じですかね。

def get_first_from_sorted(args, key, reverse):
    if len(args) == 1:
        args = iter(args[0])
    return sorted(args, key=key, reverse=reverse)[0]

def min(*args, key=None):
    return get_first_from_sorted(args, key, False)

def max(*args, key=None):
    return get_first_from_sorted(args, key, True)

とりあえず5問目は前の数題より全然簡単で少し驚きました。