Pythonの複数の戻り値を無視する


274

タプルで複数の値を返すPython関数があるとします。

def func():
    return 1, 2

一時的な変数に割り当てるだけでなく、結果の1つを無視する良い方法はありますか?私が最初の値だけに興味を持っていたとしたら、これより良い方法があります:

x, temp = func()

2
これも、特定の戻り変数を無視する構文として使用する、関数の出力無視するというMatlabの同様の概念に由来することに興味を~
持ちました

3
ソリューションとして間違った回答を選択した
AGP

回答:


242

一般的な規則の1つは、無視するタプルの要素の変数名として「_」を使用することです。例えば:

def f():
    return 1, 2, 3

_, _, x = f()

89
-1:この「慣例」は、gettext機能を他の誰かのコード(「_」と呼ばれる関数を定義する)に追加するときに機能しないため、禁止する必要があります
nosklo

27
良い点-「」と呼ばれる関数をインストールするgettextの主張が良い考えかどうかは議論の余地がありますが。個人的には少し見苦しいです。とにかく、使い捨て変数としての " " の使用は広く普及しています。
ブライアンクラッパー

25
-1:_はIPythonで「最後の出力」を意味します。私はそれに何かを割り当てることはありません。
エンドリス

20
わかりました、「I」に気づきませんでした-参照ありがとうございます。私見では、1つのPythonアプリが独自の魔法の使用を定義しているという理由だけで、他の人が変数を使用しないと期待することはできません。
ドラえもん

8
未使用の変数があるため、PyDevなどの一部のIDEでは警告が表示されます。
teeks99

595

を使用x = func()[0]して、最初の値x = func()[1]を返したり、2番目の値を返したりすることができます。

一度に複数の値を取得する場合は、などを使用しますx, y = func()[2:4]


92
これは受け入れられる答えになるはずです。一部の戻り値func()[2:4]のみが必要な場合などにも使用できます。
内部石2011

11
関数を複数回呼び出すことはありません。>>> def test():... print "here" ... return 1,2,3 ... >>> a、b = test()[:2 ]ここ[編集:コードが通らなかったのは残念です。どうやら、コメントは1行しか表示されません。馴染みのない人のために>>>と...はPythonシェルの新しい行の始まりです]
teeks99

32
@TylerLong:_, _, _, _, _, _, _, _, _, _, _, _, _, a, _, _, _, _, _, _, _, _, _, _, _, b, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, c, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, d, _, _, _, _, _, _, _, _, e, _ = func()関数を複数回呼び出すほど明確ではないと思いますが、それは私の意見です。もしあなたの関数の戻り多くの項目は、私が望ましいだろうnumpyのを使用して考えること:a, b, c, d, e = func()[[13, 25, 58, 89, 98]]
endolith

24
@endolith私はこれがより良く、numpyを必要とせず、func()を複数回呼び出す必要がないと思います:result = func() a = result[13] b = result[25]...
Tyler Long

3
間にある1つまたはいくつかの値を無視する場合、このスタイルはx, __, y = func()
適切で

96

Python 3を使用している場合は、(割り当ての左側にある)変数の前にあるスターを使用して、展開時にリストにすることができます。

# Example 1: a is 1 and b is [2, 3]

a, *b = [1, 2, 3]

# Example 2: a is 1, b is [2, 3], and c is 4

a, *b, c = [1, 2, 3, 4]

# Example 3: b is [1, 2] and c is 3

*b, c = [1, 2, 3]       

# Example 4: a is 1 and b is []

a, *b = [1]

2
を使用a, *_ = f()して、の後の任意の数の戻り値を無視することもできますa
THN

21

複数のアイテムを返すときは、実際にはタプルを返すことを忘れないでください。したがって、次のようなことができます。

def func():
    return 1, 2

print func()[0] # prints 1
print func()[1] # prints 2

17

_多くの人が以前にここで示したように、一般的な方法は、ダミー変数(単一の下線)を使用することです。

ただし、その変数名の他の使用法との衝突を回避するには(この応答を参照)__ncoghlanが指すように、使い捨て変数として(二重下線)を使用することをお勧めします。例えば:

x, __ = func()

まったく悪い考えではありません。しかし、 '_ _'は名前空間で変数を宣言します。一方、 '_'は、上記のように代入ステートメントの左側で特に使用されていない限り宣言しません(例:)a, _, _ = 1,8,9。その時点までは、最後に実行されたステートメントの結果が格納されます。キャッチしたい場合は、通常、変数を使用してその値を格納します。そして、これが「_」がジャンク値をキャッチするための推奨変数名である理由です。'_'値は、別のステートメントが実行された直後に上書きされます。'_ _'の場合、GCが消去するまで値が残ります。
Archit Kapoor

16

3つの簡単な選択肢。

明白な

x, _ = func()

x, junk = func()

恐ろしいです

x = func()[0]

そして、デコレータでこれを行う方法があります。

def val0( aFunc ):
    def pick0( *args, **kw ):
        return aFunc(*args,**kw)[0]
    return pick0

func0= val0(func)

5
私は_変数を本当に好みます。値を無視していることは明らかです
Claudiu

21
あなたの例は逆です。 x, _ = func()恐ろしいし、x = func()[0]明白です。変数に割り当ててからそれを使用しないのですか?関数はタプルを返しています。タプルのようにインデックスを付けます。
endolith

6
Pythonがこのパターンを導出したパターンマッチング言語では、「明白な」メソッドは確かに明白であり、恐ろしくなく、標準的です。ただし、そのような言語ではワイルドカードがサポートされている言語機能ですが、Pythonでは実際の変数であり、バインドされます。これは少し不快です。
Joe

4
Pythonの派生元;)であるリスト処理言語の場合a[0]a[:](リストコピー)、a[::2](2つの要素ごと)、(a[i:] + a[:i]リストを回転する)などのリストアクセサーは、確かに、明白かつ標準的です。
cod3monk3y 2014年

7

おそらく、最善の解決策は、無意味なタプルを返すのではなく、名前を付けることです。返されたアイテムの注文の背後にあるロジックがない限り。

def func():
    return {'lat': 1, 'lng': 2}

latitude = func()['lat']

返すものに関する追加情報を追加したい場合は、namedtupleを使用することもできます(これは単なる辞書ではなく、座標です)。

from collections import namedtuple 

Coordinates = namedtuple('Coordinates', ['lat', 'lng'])

def func():
    return Coordinates(lat=1, lng=2)

latitude = func().lat

辞書/タプル内のオブジェクトが強く結びついている場合は、そのクラスを定義することもお勧めします。このようにして、このタイプのオブジェクト間の相互作用を定義し、それらのオブジェクトの操作方法に関するAPIを提供することもできます。次の自然な質問:Pythonでクラスを使用する必要があるのはいつですか?


4

これは私にとって最良の選択のようです:

val1, val2, ignored1, ignored2 = some_function()

(func()[index]メソッドのように)不可解で醜いものではなく、目的を明確に示しています。


4

これは質問に対する直接の回答ではありません。むしろ、「多くの可能なオプションから特定の関数出力を選択するにはどうすればよいですか?」という質問に答えます。

関数を記述できる場合(つまり、ライブラリにないため、変更できない場合)、関数に必要なものを示す入力引数を追加します。「一般的なケース」では指定する必要がないように、デフォルト値の名前付き引数にします。

    def fancy_function( arg1, arg2, return_type=1 ):
        ret_val = None
        if( 1 == return_type ):
            ret_val = arg1 + arg2
        elif( 2 == return_type ):
            ret_val = [ arg1, arg2, arg1 * arg2 ]
        else:
            ret_val = ( arg1, arg2, arg1 + arg2, arg1 * arg2 ) 
        return( ret_val )

このメソッドは、目的の出力に関する関数「事前警告」を提供します。その結果、不要な処理をスキップして、目的の出力を取得するために必要な作業のみを実行できます。また、Pythonは動的型付けを行うため、戻り値の型が変わる可能性があります。例がスカラー、リスト、またはタプルを返す方法に注意してください。


2

これが常に使用する関数であり、常に2番目の引数を破棄する場合、を使用して2番目の戻り値なしで関数のエイリアスを作成するほうが煩雑ではないと私は主張しますlambda

def func():
    return 1, 2

func_ = lambda: func()[0] 

func_()  # Prints 1 

2

関数からの多くの出力があり、それを複数回呼び出したくない場合、結果を選択する最も明確な方法は次のようになると思います。

results = fct()
a,b = [results[i] for i in list_of_index]

最小限の実例として、関数が1回だけ呼び出されることも示しています。

def fct(a):
    b=a*2
    c=a+2
    d=a+b
    e=b*2
    f=a*a
    print("fct called")
    return[a,b,c,d,e,f]

results=fct(3)
> fct called

x,y = [results[i] for i in [1,4]]

そして、値は期待通りです:

results
> [3,6,5,9,12,9]
x
> 6
y
> 12

便宜上、Pythonリストインデックスも使用できます。

x,y = [results[i] for i in [0,-2]]

戻り値:a = 3およびb = 12

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.