タプルで複数の値を返す Python 関数があるとします。
def func():
return 1, 2
一時変数に代入するだけでなく、結果の 1 つを無視する良い方法はありますか? 最初の値だけに興味がある場合、これよりも良い方法はありますか?
x, temp = func()
を使用x = func()[0]
して、最初の値x = func()[1]
を返したり、2 番目の値を返したりすることができます。
一度に複数の値を取得したい場合は、 のようなものを使用しますx, y = func()[2:4]
。
一般的な規則の 1 つは、無視するタプルの要素の変数名として「_」を使用することです。例えば:
def f():
return 1, 2, 3
_, _, x = f()
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]
複数のアイテムを返す場合、実際にはタプルを返していることを忘れないでください。したがって、次のようなことができます。
def func():
return 1, 2
print func()[0] # prints 1
print func()[1] # prints 2
シンプルな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)
おそらく最良の解決策は、無意味なタプルを返す代わりに名前を付けることです (返されるアイテムの順序の背後に何らかのロジックがある場合を除きます)。たとえば、辞書を使用できます。
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
ディクショナリ/タプル内のオブジェクトが強く結び付けられている場合は、クラスを定義することをお勧めします。そうすれば、より複雑な操作を定義することもできます。次の自然な質問は、Python でクラスをいつ使用する必要があるかということです。
Python の最新バージョン (≥ 3.7) には、ごくわずかなコード行でクラスを定義するために使用できるデータクラスがあります。
from dataclasses import dataclass
@dataclass
class Coordinates:
lat: float = 0
lng: float = 0
def func():
return Coordinates(lat=1, lng=2)
latitude = func().lat
namedtuple に対するデータクラスの主な利点は、拡張が容易なことですが、他にも違いがあります。デフォルトでは、データクラスは可変ですが、強制的に不変にする@dataclass(frozen=True)
代わりに使用できることに注意してください。@dataclass
ユース ケースに適したデータ クラスを選択するのに役立つビデオを次に示します。
これは私にとって最良の選択のようです:
val1, val2, ignored1, ignored2 = some_function()
これは ( func()[index] メソッドのように) 難解でも醜いものでもなく、目的を明確に示しています。
これは質問に対する直接的な回答ではありません。むしろ、「多くの可能なオプションから特定の関数出力を選択するにはどうすればよいですか?」という質問に答えます。
関数を記述できる場合 (つまり、変更できないライブラリに含まれていない場合)、関数から何を求めるかを示す入力引数を追加します。デフォルト値を持つ名前付き引数にして、「一般的なケース」では指定する必要さえありません。
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 は動的型付けを行うため、戻り値の型が変わる可能性があります。この例がどのようにスカラー、リスト、またはタプルを返すかに注目してください。
関数からの出力が多く、それを複数回呼び出したくない場合、結果を選択する最も明確な方法は次のようになると思います。
results = fct()
a,b = [results[i] for i in list_of_index]
最小限の作業例として、関数が一度だけ呼び出されることも示しています。
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