rohaniのブログ

ゆるっと自然言語処理奴。ときどき工作系バイト。

操作なのか、値を返すのか

リスト末尾に要素を追加して返す関数を書こうと思った。

(実際にはもう少し複雑なことをしていたのだけれど)以下のような間違いをした。

def append_hoge(lst):
    return lst.append('hoge')

lst = ['Hello']
print(append_hoge(lst))
#> None

気持ち的には、

def add_hoge(str):
    return str + 'hoge'

str = 'Hello '
print(add_hoge(str))
#> Hello hoge

こんな気持ちで書いていた。

しかしこの二つには大きな違いがある。それは、Pythonのappendは戻り値を返さないということ。

list.append(x)
   リストの末尾に要素を一つ追加します。a[len(a):] = [x] と等価です。
5. データ構造 — Python 3.6.5 ドキュメント

だから、正しくは

def append_hoge(lst):
    lst.append('hoge')
    return lst

lst = ['Hello']
print(append_hoge(lst))
#> None

ただし、pythonの関数に渡されるリストは参照渡しなので、

def append_hoge(lst):
    lst.append('hoge')

lst = ['Hello']
append_hoge(lst)
print(lst)
#> None

こっちでも同じように動く。

id() で確認して見たところ、代入し直しても領域が別に取られてしまうということもなかったので、 どちらがいいのかは私には分からない...。参照なんだから、returnするとややこしくなると考えると後者の方が綺麗なのかな?どうだろう。