質問

は何ですか * Python の演算子 means (次のようなコードなど) zip(*x) または f(**k)?

  1. インタプリタ内部ではどのように処理されるのでしょうか?
  2. パフォーマンスにまったく影響はありませんか?速いですか、それとも遅いですか?
  3. それが役立つのはどんなときで、そうでないのはどんなときでしょうか?
  4. 関数宣言または呼び出しで使用する必要がありますか?
役に立ちましたか?

解決

シングルスター * シーケンス/コレクションをポジショナル引数に梱包するので、これを行うことができます。

def sum(a, b):
    return a + b

values = (1, 2)

s = sum(*values)

これにより、タプルが展開され、実際には次のように実行されます。

s = sum(1, 2)

ダブルスター ** 同じことをして、辞書のみを使用して、したがって引数の名前が付けられています。

values = { 'a': 1, 'b': 2 }
s = sum(**values)

組み合わせることもできます。

def sum(a, b, c, d):
    return a + b + c + d

values1 = (1, 2)
values2 = { 'c': 10, 'd': 15 }
s = sum(*values1, **values2)

asを実行します:

s = sum(1, 2, c=10, d=15)

セクションも参照してください 4.7.4-引数リストを開梱します Pythonドキュメントの。


さらに、実行する関数を定義できます *x**y 引数では、これにより、関数が宣言に具体的に指定されていない任意の数の位置および/または指名された引数を受け入れることができます。

例:

def sum(*values):
    s = 0
    for v in values:
        s = s + v
    return s

s = sum(1, 2, 3, 4, 5)

または **:

def get_a(**values):
    return values['a']

s = get_a(a=1, b=2)      # returns 1

これにより、宣言することなく、多数のオプションパラメーターを指定できます。

繰り返しますが、組み合わせることができます。

def sum(*values, **options):
    s = 0
    for i in values:
        s = s + i
    if "neg" in options:
        if options["neg"]:
            s = -s
    return s

s = sum(1, 2, 3, 4, 5)            # returns 15
s = sum(1, 2, 3, 4, 5, neg=True)  # returns -15
s = sum(1, 2, 3, 4, 5, neg=False) # returns 15

他のヒント

1つの小さなポイント:これらは演算子ではありません。演算子は、既存の値から新しい値を作成するために式で使用されます(たとえば、1+2は3になります。 *および**は、関数宣言と呼び出しの構文の一部です。

これは、関数呼び出しを「保存」したい場合に特に役立ちます。

たとえば、関数「add」のユニットテストがいくつかあるとします。

def add(a, b): return a + b
tests = { (1,4):5, (0, 0):0, (-1, 3):3 }
for test, result in tests.items():
   print 'test: adding', test, '==', result, '---', add(*test) == result

ADD(TEST [0]、test [1])のようなものを手動で行う以外に、ADDを呼び出す他の方法はありません。また、変数数の変数がある場合、コードは必要なすべてのIFステートメントでかなり醜くなる可能性があります。

これが役立つもう1つの場所は、工場オブジェクト(あなたのためにオブジェクトを作成するオブジェクト)を定義するためのものです。クラスの工場があると仮定します。それは車のオブジェクトを作り、それらを返します。 myFactory.make_car( 'red'、 'bmw'、 '335ix')が車( 'red'、 'bmw'、 '335ix')を作成してから返します。

def make_car(*args):
   return Car(*args)

これは、スーパークラスのコンストラクターを呼び出す場合にも役立ちます。

これは拡張呼び出し構文と呼ばれます。から ドキュメンテーション:

構文 *expression が関数呼び出しに出現する場合、expression はシーケンスとして評価される必要があります。このシーケンスの要素は、追加の位置引数であるかのように扱われます。位置引数 x1,..., xN があり、expression がシーケンス y1, ..., yM として評価される場合、これは M+N の位置引数 x1, ..., xN, y1, ... を使用した呼び出しと同等です。 ...、yM。

そして:

構文 **expression が関数呼び出しに出現する場合、expression はマッピングとして評価される必要があり、その内容は追加のキーワード引数として扱われます。キーワードが式と明示的なキーワード引数の両方に出現する場合、TypeError 例外が発生します。

関数コールでは、シングルスターがリストを別々の引数に変換します(例: zip(*x) と同じです zip(x1,x2,x3) もしも x=[x1,x2,x3])そして、ダブルスターは辞書を別々のキーワード引数に変えます(例: f(**k) と同じです f(x=my_x, y=my_y) もしも k = {'x':my_x, 'y':my_y}.

関数定義では、それはその逆です。単一の星は任意の数の引数をリストに変え、ダブルスタートは任意の数のキーワード引数を辞書に変えます。例えば def foo(*x) 「fooは任意の数の引数を取り、リストxからアクセスできます(すなわち、ユーザーが呼び出す場合 foo(1,2,3), x そうなるでしょう [1,2,3])" と def bar(**k) 「barは任意の数のキーワード引数を取得し、辞書kからアクセスできます(すなわち、ユーザーが呼び出す場合 bar(x=42, y=23), k そうなるでしょう {'x': 42, 'y': 23})".

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top