1

numpyのようなライブラリを使用せずに、メンバー関数に数学的な argmin/argmax を使用する「pythonic」な方法があるかどうかを知りたいです。

内部に整数を返すメンバー関数を持つクラスがあります。このクラスのいくつかのオブジェクトをインスタンス化します。このメソッドの戻り値が低いオブジェクトを知りたいです。

以下のソースコードを見つけてください。改善したい部分はコード 改善したいタグの直後です。このコードは非常にうまく機能していますが、同じことを行うためのより良い方法があると確信しています。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""argmin example"""


class People(object):
    """People class"""
    ret_ages = {"Half": 60, "AlmostFull": 65, "Full": 71}  # years

    def __init__(self, name, age, ret_mode):
        super(People, self).__init__()

        if ret_mode not in self.ret_ages.keys():
            raise KeyError(ret_mode + " not in " + str(self.ret_ages.keys()))

        self.name = name
        self.age = age
        self.ret_mode = ret_mode

    def get_remaining_years(self):
        """
                Return how many years People have still to work before earning
                <rate> retirement.
                <rate> could be "Half", "Middle" or "Full".
        """
        try:
            return self.ret_ages[self.ret_mode] - self.age
        except KeyError:
            raise KeyError("rate has to be in " + str(self.ret_ages.keys()))


def main():
    """Main function"""
    people_list = [
        People("Juliette", 35, "Full"),
        People("Coralie", 26, "Half"),
        People("Laura", 27, "AlmostFull")
    ]

    # Debugging print
    for people in people_list:
        print people.name, "has still to work",\
            people.get_remaining_years(), "years."
    print
    # End of debugging print

    ############################
    # Code I'd like to improve #
    ############################

    people_closer_to_ret = people_list[0]
    minimum_remainining_years = people_closer_to_ret.get_remaining_years()

    for people in people_list:
        if people.get_remaining_years() < minimum_remainining_years:
            people_closer_to_ret = people
            minimum_remainining_years = people.get_remaining_years()

            minimum_remainining_years = people.get_remaining_years()

    ###################################
    # End of code I'd like to improve #
    ###################################

    print people_closer_to_ret.name, "will be retired soon !"


if __name__ == '__main__':
    main()

このスクリプトの出力は次のとおりです。

Juliette has still to work 36 years.
Coralie has still to work 34 years.
Laura has still to work 38 years.

Coralie will be retired soon !
4

1 に答える 1

2

このコードをよりPythonicな方法で記述する良い方法は、 min関数を使用することです。これは、パラメーターkeyのおかげで、実際にはargmin関数のように使用できます。

タグCode I'd like to ImprovementEnd of code I'd like to Improvement by の間のコードを置き換えると:

people_closer_to_ret = min(people_list,
                           key=lambda people: people.get_remaining_years()),

それは完璧に機能しています。key引数は、最小化する必要がある基準をmin関数に伝えるのに役立ちます。

したがって、完全なコードは次のとおりです。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""argmin example"""


class People(object):
    """People class"""
    ret_ages = {"Half": 60, "AlmostFull": 65, "Full": 71}  # years

    def __init__(self, name, age, ret_mode):
        super(People, self).__init__()

        if ret_mode not in self.ret_ages.keys():
            raise KeyError(ret_mode + " not in " + str(self.ret_ages.keys()))

        self.name = name
        self.age = age
        self.ret_mode = ret_mode

    def get_remaining_years(self):
        """
                Return how many years People have still to work before earning
                <rate> retirement.
                <rate> could be "Half", "Middle" or "Full".
        """
        try:
            return self.ret_ages[self.ret_mode] - self.age
        except KeyError:
            raise KeyError("rate has to be in " + str(self.ret_ages.keys()))


def main():
    """Main function"""
    people_list = [
        People("Juliette", 35, "Full"),
        People("Coralie", 26, "Half"),
        People("Laura", 27, "AlmostFull")
    ]

    # Debugging print
    for people in people_list:
        print people.name, "has still to work",\
            people.get_remaining_years(), "years."
    print
    # End of debugging print

    people_closer_to_ret = min(people_list,
                               key=lambda people: people.get_remaining_years())

    print people_closer_to_ret.name, "will be retired soon !"


if __name__ == '__main__':
    main()
于 2016-06-05T23:33:49.587 に答える