3

関数定義で二重星構文を使用して、通常の辞書を取得します。問題は、ユーザーの入力順序が失われることです。場合によっては、キーワード引数が関数に渡される順序を知りたい場合があります。

通常、関数呼び出しは多くの引数を必要としないため、パフォーマンスの問題ではないと思いますが、デフォルトで順序を維持しないのはなぜでしょうか。

私たちが使用できることを知っています:

from collections import Ordereddict
def my_func(kwargs):
    print kwargs
my_func(Ordereddict(a=1, b=42))

ただし、以下よりも簡潔ではありません。

def my_func(**kwargs):
    print kwargs
my_func(a=1, b=42)

[編集1]:

1)2つのケースがあると思いました:

  • 順序を知る必要があります。この動作は、ドキュメントを通じてユーザーに知られています。
  • 注文はいらないので、注文してもしなくても構いません。

ユーザーが注文を使用していることを知っていても、次のように使用できるとは思いませんでした。

a = dict(a=1, b=42)
my_func(**a)

dict が順序付けされていないことを知らなかったからです (知っているはずなのに)

2) 少数の引数の場合、オーバーヘッドはそれほど大きくないと考えたので、引数を管理する新しい可能性を持つことの利点は、この欠点よりも優れています。

しかし、(ジョーの答えから)オーバーヘッドは無視できないようです。

[編集2]:

PEP 0468 -- Preserving the order of **kwargs in a functionはこの方向に向かっているようです。

4

4 に答える 4

7

辞書は定義によって順序付けられていないためです。本当に単純なことだと思います。ポイントは、kwargs順序付けされていない仮パラメータを正確に処理することです。順序がわかっている場合は、それらを「通常の」パラメーターまたは として受け取ることができます*args

ここに辞書の定義があります。

CPython 実装の詳細: キーと値は任意の順序でリストされます。これはランダムではなく、Python 実装によって異なり、辞書の挿入と削除の履歴に依存します。

http://docs.python.org/2/library/stdtypes.html#dict

Python の辞書は、言語全体が機能する方法の中心であるため、高度に最適化されています。順序付けを追加すると、パフォーマンスに影響を与え、より多くのストレージと処理のオーバーヘッドが必要になります。

そうでない場合もあるかもしれませんが、それは一般的というよりは例外的だと思います。非常にホットなコード パスに「念のため」機能を追加することは、賢明な設計上の決定ではありません。

編集:

参考までに

>>> timeit.timeit(stmt="z = dict(x)", setup='x = ((("one", "two"), ("three", "four"), ("five", "six")))', number=1000000)
1.6569631099700928

>>> timeit.timeit(stmt="z = OrderedDict(x)", setup='from collections import OrderedDict; x = ((("one", "two"), ("three", "four"), ("five", "six")))', number=1000000)
31.618864059448242

これは、小さい「通常の」サイズの辞書を作成する場合、約 30 倍の速度の違いです。OrderedDict は標準ライブラリの一部であるため、これ以上のパフォーマンスを引き出すことはできないと思います。

于 2013-08-06T10:16:58.113 に答える
0

関数の引数が非常に相関しているため、名前と順序の両方が問題になる場合は、特定のデータ構造を使用するか、それらを保持するクラスを定義することを検討してください。おそらく、コード内の他の場所でそれらをまとめて使用し、それらを使用する他の関数/メソッドを定義する可能性があります。

于 2013-08-06T12:00:40.423 に答える
0

**kwargs を介して渡されたキーワード引数の順序を取得することは、私が取り組んでいる特定のプロジェクトで非常に役立ちます。これは、意味のある次元 (現在は dimarray と呼ばれる) を持つ一種の nd numpy 配列を作成することであり、特に地球物理データの処理に役立ちます。

ここに例を含む開発された質問を投稿しました:

関数呼び出しに渡されたキーワード引数の元の順序を取得する方法は?

于 2013-12-01T16:00:50.563 に答える