tl; dr(ダックタイピング)
これらすべてのデータ構造にいくつかの類似点があるのは正しいことです。Pythonはダックタイピングを使用していることを忘れないでください(アヒルのように見え、アヒルのようにクワックする場合は、アヒルです)。同じ状況で2つのオブジェクトを使用できる場合、現在の目的と目的では、それらは同じデータ型である可能性があります。ただし、他の状況で使用しようとすると、同じように動作しなくなる可能性があることに常に注意する必要があります。
これを念頭に置いて、あなたが言及した4つのデータ型について実際に何が異なり、同じであるかを調べて、それらが交換可能である状況の一般的な考え方を理解する必要があります。
可変性(変更できますか?)
辞書、リスト、およびセットに変更を加えることができます。タプルは、コピーを作成せずに「変更」することはできません。
可変:dict
、、list
set
不変:tuple
Pythonstring
も不変の型です。なぜ不変のオブジェクトが必要なのですか?私はこの答えから言い換えます:
不変オブジェクトは多くの場合最適化できます
Pythonでは、不変のものだけがハッシュ可能です(そして、ハッシュ可能なオブジェクトだけがセットのメンバー、または辞書のキーになることができます)。
このプロパティを比較すると、リストとタプルは「最も近い」2つのデータ型のように見えます。高レベルでは、タプルはリストの不変の「フリーズフレーム」バージョンです。これにより、リストは時間の経過とともに変化するデータセットに役立ちますが(リストを変更するためにリストをコピーする必要がないため)、タプルは辞書キー(不変の型である必要があります)などに役立ちます。
順序付け(および抽象データ型に関する注記)
セットのような辞書には、固有の概念的な順序はありません。これは、順序があるリストやタプルとは対照的です。dictまたはセット内のアイテムの順序はプログラマーから抽象化されています。つまり、要素Aがfor k in mydata
ループ内でBの前にある場合、開始後にAがBの前にあることに依存するべきではありません(通常は信頼できません)。に変更を加えるmydata
。
順序を維持する:list
、tuple
非順序保持:dict
、set
技術的には、2回続けて繰り返すmydata
と同じ順序になりますが、これはPythonの仕組みの便利な機能であり、実際にはset
抽象データ型(データ型の数学的定義)の一部ではありません。 。ただし、リストとタプル、特に不変のタプルは順序を保証します。
繰り返したときに見えるもの(アヒルのように歩く場合...)
ここでは、辞書の不変の類似物として、各要素の名前と値の両方を持つ名前付きタプルを見ることができると思います。ただし、これは微妙な比較です。名前付きタプルで辞書のみのメソッドを使用しようとすると、ダックタイピングで問題が発生することを覚えておいてください。その逆も同様です。
あなたの質問への直接の回答
辞書は、特定の一意性制約を持つタプルの単なるリストではありませんか?
いいえ、いくつかの違いがあります。辞書には固有の順序はありません。これは、リストとは異なります。
また、ディクショナリには、各「要素」のキーと値があります。一方、タプルは任意の数の要素を持つことができますが、それぞれに値しかありません。
キーがセットのように機能する辞書の仕組みにより、キーがあれば一定時間で値を検索できます。タプルのリスト(ここではペア)では、キーが見つかるまでリストを反復処理する必要があります。つまり、検索はリスト内の要素の数で線形になります。
ただし、最も重要なのは、辞書の項目は変更できますが、タプルは変更できないことです。
リストは、異なる種類の一意性制約を持つ単なるセットではありませんか?
繰り返しになりますが、リストには固有の順序がありますが、セットには固有の順序がないことを強調しておきます。これにより、リストは、アイテムを追加した順序を覚えておきたいスタックやキューなどを表すのに非常に便利になります。セットはそのような保証を提供しません。ただし、メンバーシップのルックアップを一定時間で実行できるという利点がありますが、リストには線形時間がかかります。
現在、タプルという名前が付けられています。これは、特殊なケースの辞書のように感じ始めています。現在、順序付けられた辞書があり、リストのように感じ始めています。そして、注文したセットのレシピを見たところです。私はこれが続いていることを想像することができます...ユニークなリストなどはどうですか?
ある程度同意します。ただし、データ構造ライブラリは、すでに確立されているデータ構造の一般的なユースケースをサポートするのに役立ちます。これにより、プログラマーは標準構造のカスタム拡張機能を考え出すのに時間を無駄にすることがなくなります。手に負えなくなることがなく、各ソリューションに独自の有用性が見られる限り、棚に車輪を置いておくとよいので、再発明する必要はありません。
良い例はCounter()クラスです。この特殊な辞書は、数え切れないほど何度も使用されており(badoom-tshhhhh!)、カスタムソリューションをコーディングする手間を省くことができました。カスタムデータ構造フォルダーにあり、年に1〜2回しか使用されないものよりも、コミュニティが適切なPythonのベストプラクティスを開発して維持するのに役立つソリューションが欲しいです。