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

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

ただいまの
回答率

88.62%

Python:return文での値の返し方

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 577

Ykkykk

score 118

Pythonの関数でreturn文を書く際の値の返し方についての質問です。

関数内でなんらかの処理をして算出された値をリストにして返したいときに、
returnの部分でリストを作成する操作をするよりも、あらかじめ変数にしてしまって返したほうがよいのでしょうか?

def function():
  lst = [1, 2]
  a = lst[0] + lst[1]
  b = lst[0] - lst[1]
  c = lst[0] * lst[1]
  d = lst[0] / lst[1]
  return list((a, b, c, d))


このような返し方をするのと、

def function():
  lst = [1, 2]
  lst2 = []
  a = lst[0] + lst[1]
  lst2.append(a)
  b = lst[0] - lst[1]
  lst2.append(b)
  c = lst[0] * lst[1]
  lst2.append(c)
  d = lst[0] / lst[1]
  lst2.append(d)
  return lst2


以上のような返し方をするのとでは処理に違いが生じているのでしょうか?
ご教示いただけますと幸いです。よろしくお願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+3

上は(a,b,c,d)tupleを作ってからlistに変換、下はlst2 = []を作ってそれぞれをappendですから、処理の内容は違います。

パフォーマンスはともかく、下のコードはやたら冗長ですから、避けたほうが良いでしょう。


listを返したい」ということであれば、私ならこう書くと思います。

def function():
    lst = [1, 2]
    a = lst[0] + lst[1]
    b = lst[0] - lst[1]
    c = lst[0] * lst[1]
    d = lst[0] / lst[1]
    return [a, b, c, d]

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/03 10:06

    ご回答いただきありがとうございます。一つ目はタプルを作ってからリストに変換という処理になっているのですね。
    returnの部分でリストを作成する操作をした方がすっきりする感じですね。
    ありがとうございました!

    キャンセル

+2

私なら、タプルのまま返して呼び出し元でリストに変換します。

def function():
    lst = [1, 2]
    return lst[0]+lst[1], lst[0]-lst[1], lst[0]*lst[1], lst[0]/lst[1]

ret = function()
print(ret, list(ret))

実行結果 Wandbox

(3, -1, 2, 0.5) [3, -1, 2, 0.5]

個人的には、イテラブルな返り値をリストに変換するのは呼び出し元の責任だと思っています。

理由

ぱっと思い付いた理由は、次の二つです。

処理が関数の実装に影響されること
関数がグローバルなリストを返してくる恐れがあります。
返り値を安心して使うためには、どちらにせよオブジェクトを再生成しなくてはいけません。

例えば、こんなふうに関数が実装されていたとします。

def function():
    return lst

返り値の使い方に依っては、副作用が生じます。

>>> lst = []
>>> ret = function()
>>> ret.append(42)
>>>
>>> print(lst)
[42]
>>> ret is lst
True
>>> lst = []
>>> ret = list(function())
>>> ret.append(42)
>>>
>>> print(lst)
[]
>>> ret is lst
False

遅延評価のメリットを潰しかねないこと
関数をジェネレータとして実装することで、パフォーマンスの向上を図ることができます。

例えば、長い時間を要する処理を繰り返す関数があるとします。
そのような関数は、ジェネレータ関数として実装することで処理を分散するのが一般的です。

def function():
    for _ in range(3):
        print('wasting time...')
        yield 42

全体の実行時間は短縮されませんが、待ち時間の集中に依るストレスは幾分か緩和されます。

>>> for e in function():
...     print('got e')
...
wasting time...
got e
wasting time...
got e
wasting time...
got e
>>>

返り値をリストとして得たい場合は、呼び出し元で明示的に変換してやります。

>>> lst = list(function())
wasting time...
wasting time...
wasting time...
>>>

最初からリストを返すような実装だと、目的に応じて使い分けられるメリットが潰れます。

おまけ

変わり種。

import operator as op


def function():
    return map(
        lambda f: f(1, 2),
        [op.add, op.sub, op.mul, op.truediv]
    )

ret = function()
print(ret, list(ret))

実行結果 Wandbox

<map object at 0x7fe52abcf080> [3, -1, 2, 0.5]

Python2.7のmapはリストを返す仕様でした。
3.0以降でイテレータを返す仕様に変更されたのは、前述の二番目の理由に依るものです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/03 16:30

    ご回答いただきありがとうございます。
    そういった考え方が全くわからないため質問いたしました。
    呼び出し元でリストにする方が良いという考え方もあるのですね。
    また、変わり種のやり方についてもお教えいただきありがとうございます。勉強になりました。
    ありがとうございました!

    キャンセル

  • 2018/12/03 16:57

    呼び出し元でリストに変換する方が良いと思う理由について追記しました。
    それなりにややこしい話であるうえに、じゃっかん質問の本旨から逸れてしまいましたので、気が向いたときにでもご覧いただければ結構です。

    キャンセル

  • 2018/12/03 18:11

    詳細な解説までご追記くださりありがとうございます。
    こういった考え方については解説用のサイトや書籍では見たことがないため、大変勉強になります。
    ありがとうございます。

    キャンセル

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

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る