2

Python には、データをモデル化するための優れた構造がいくつかあります。ここにあるいくつかの :

              +-------------------+-----------------------------------+
              | indexed by int    | no-indexed by int                 |
+-------------+-------------------+-----------------------------------+
| no-indexed  | [1, 2, 3]         | {1, 2, 3}                         |
| by key      | or                | or                                |
|             | [x+1 in range(3)] | {x+1 in range(3)}                 |
+-------------+-------------------+-----------------------------------+
| indexed     |                   | {'a': 97, 'c': 99, 'b': 98}       |
| by key      |                   | or                                |
|             |                   | {chr(x):x for x in range(97,100)} |
+-------------+-------------------+-----------------------------------+

Python がデフォルトで key+int によってインデックス付けされた構造体 (PHP 配列など) を含まないのはなぜですか? このオブジェクトをエミュレートするライブラリがあることは知っています ( http://docs.python.org/3/library/collections.html#ordereddict-objects )。しかし、ドキュメントから取得した「orderedDict」の表現は次のとおりです。

OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])

論理的に次のように書かれるべきネイティブ型を持っている方が良いのではないでしょうか:

['a': 97, 'b': 98, 'c': 99]

また、orderedDict 内包表記の同じロジック:

[chr(x):x for x in range(97,100)]

Python の設計で、このように表のセルを埋めるのは理にかなっていますか? これがまだ実装されていない特定の理由はありますか?

4

4 に答える 4

17

Python の辞書は、ハッシュ テーブルとして実装されています。これらは本質的に順序付けられていないデータ構造です。collections.OrderedDict( Python 2.7 および 3.1+ で行われているように) 順序を追跡するために追加のロジックを追加することは可能ですが、重要なオーバーヘッドが関係しています。

たとえば、ドキュメントが Python 2.4-2.6 での使用を提案しているレシピでは、collections多くの基本的な辞書操作 (値の追加や削除など) を完了するために 2 倍以上の作業が必要になります。これは、順序付けられた反復に使用する二重リンク リストを維持する必要があり、リストを維持するために追加の辞書が必要なためです。その演算は依然として O(1) ですが、定数項は大きくなっています。

Python はdictあらゆる場所でインスタンスを使用するため (たとえば、すべての変数検索など)、非常に高速である必要があります。そうしないと、すべてのプログラムのすべての部分が犠牲になります。順序付けられた反復は頻繁に必要とされるわけではないため、一般的な場合に必要なオーバーヘッドを回避することは理にかなっています。順序付けされた辞書が必要な場合は、標準ライブラリにあるものを使用してください (以前のバージョンの Python を使用している場合は、標準ライブラリが提案するレシピを使用してください)。

于 2012-11-13T03:56:53.277 に答える
4

あなたの質問は、「Python には、順序付けられたキーを持つネイティブ PHP スタイルの配列がないのはなぜですか?」のようです。

Python には、list、dict、および tuple という 3 つの主要な非スカラー データ型があります。dicts と tuples は、言語自体を実装するために絶対に不可欠です。これらは、割り当て、引数のアンパック、属性検索などに使用されます。コア言語のセマンティクスには実際には使用されませんが、Python のデータとプログラムにはリストが非常に不可欠です。3 つすべてが非常に軽量で、セマンティクスがよく理解されており、可能な限り高速である必要があります。

PHP スタイルの配列は、これらのいずれでもありません。それらは高速でも軽量でもなく、ランタイムの複雑さの定義が不十分であり、非常に多くの異なるものに使用できるため、セマンティクスが混乱しています-配列関数を見てください。それらは実際には、作成された非常に狭い用途、つまりデータを表す用途を除いて、ほとんどすべてのユースケースでひどいx-www-form-encodedデータ型です。この使用例でも、以前のキーが後のキーの値を上書きするという失敗があります。PHP では?a=1&a=2array('a'=>2). (Python でこれを処理するための一般的な構造はMultiDictで、順序付けられたキー値があり、各キーは複数の値を持つことができます。)

PHP には、ほとんどすべてのユースケースで使用する必要があるデータ型が 1 つあります。Python には多くの異なるデータ型 (一部のコア、外部ライブラリの多く) があり、より狭いユース ケースに優れています。

于 2012-11-13T04:16:18.063 に答える