1. ホーム
  2. python

[解決済み] 関数が複数の値を返すことはpythonicですか?

2023-06-23 12:18:56

質問

Pythonでは、1つの関数が複数の値を返すことができます。 以下はその例です。

def divide(x, y):
    quotient = x/y
    remainder = x % y
    return quotient, remainder  

(q, r) = divide(22, 7)

これは非常に便利なように見えますが、悪用される可能性もありそうです("まあ、関数Xはすでに中間値として必要なものを算出していますね。 Xはその値も返すようにしましょう")。

いつ線を引いて、別のメソッドを定義すべきでしょうか?

どのように解決するのですか?

もちろんです(提供された例に対して)。

タプルはPythonの一級市民です。

ビルトイン関数である divmod() があり、これはまさにそれを行うものです。

q, r = divmod(x, y) # ((x - x%y)/y, x%y) Invariant: div*y + mod == x

他の例もある。 zip , enumerate , dict.items .

for i, e in enumerate([1, 3, 3]):
    print "index=%d, element=%s" % (i, e)

# reverse keys and values in a dictionary
d = dict((v, k) for k, v in adict.items()) # or 
d = dict(zip(adict.values(), adict.keys()))

ちなみに、括弧はほとんどの場合必要ありません。 引用元 Python ライブラリリファレンス :

タプルは様々な方法で構築することができます。

  • 空のタプルを表すために一組の括弧を使用する。()
  • シングルトンタプルを表すための末尾のカンマの使用: a, または (a,)
  • カンマで項目を区切る: a、b、c または (a、b、c)
  • tuple()組み込みの使用:tuple()または tuple(iterable)

関数は単一目的であるべき

したがって、関数は単一のオブジェクトを返さなければなりません。あなたの場合、このオブジェクトはタプルです。タプルをアドホックな複合データ構造として考えてみましょう。ほとんどすべての関数が複数の値を返す言語があります(Lispのリスト)。

を返すだけで十分な場合もあります。 (x, y) の代わりに Point(x, y) .

名前付きタプル

Python 2.6での名前付きタプルの導入により、多くの場合、プレーンタプルの代わりに名前付きタプルを返すことが望ましいとされています。

>>> import collections
>>> Point = collections.namedtuple('Point', 'x y')
>>> x, y = Point(0, 1)
>>> p = Point(x, y)
>>> x, y, p
(0, 1, Point(x=0, y=1))
>>> p.x, p.y, p[0], p[1]
(0, 1, 0, 1)
>>> for i in p:
...   print(i)
...
0
1