Pythonがタプル、リスト、セット、辞書を根本的に異なるものとして扱うのはなぜですか?

collections language-design python zen
Pythonがタプル、リスト、セット、辞書を根本的に異なるものとして扱うのはなぜですか?

Pythonが好きな理由の1つは、タプル、リスト、セット、および辞書によって提供される表現力/プログラミングの労力の削減です。 リストの理解と、INとFORを使用した基本的なパターンのいくつかを理解すれば、人生はずっと良くなります! パイソンが揺れる。

しかし、なぜこれらの構成要素が異なるように扱われるのか、そしてこれが時間とともにどのように変化する(見知らぬ人になる)のだろうか。 Python 2.xに戻って、それらはすべて基本的なコレクション型の単なるバリエーションであり、一部の非エキゾチックなユースケースでは辞書をリストに変換して再度戻す必要があるので、いらいらさせられた。 (辞書は特定の一意性制約を持つタプルのリストではありませんか? リストは、異なる種類の一意性制約を持つセットだけではありませんか?)。

3.xの世界では、より複雑になっています。 現在、名前付きタプルがあります-特別な場合の辞書のように感じ始めています。 順序付けられた辞書があります-リストのように感じ始めています。 そして、注文したセットのレシピを見ました。 これがどんどん進んでいくのを想像できます
. 一意のリストなどはどうですか

PythonのZenは、「それを行うには明らかな方法が1つ、できれば1つだけあるべきだ」と言っています。 専門的なコレクションの種類が豊富にあることは、このPythonの教訓と矛盾しているように思えます。

筋金入りのPythonistaはどう思いますか?

  22  10


ベストアンサー

tl; dr(ダックタイピング)

これらすべてのデータ構造にいくつかの類似点があることは間違いありません。 * Pythonはアヒルのタイピングを使用していることを思い出してください*(アヒルのように見え、アヒルのように鳴く場合は、アヒルです)。 同じ状況で2つのオブジェクトを使用できる場合、現在の意図と目的のために、それらは同じデータ型である可能性があります。 ただし、他の状況でそれらを使用しようとすると、それらが同じように動作しなくなる可能性があることに常に留意する必要があります。

これを念頭に置いて、言及した4つのデータ型について実際に異なる点と同じ点を調べて、それらが交換可能な状況の一般的な考え方を理解する必要があります。

可変性(変更できますか?)

辞書、リスト、およびセットを変更できます。 コピーを作成せずにタプルを「変更」することはできません。

  • 可変: dict、` list`、 set
    +不変: tuple

Pythonの `string`も不変の型です。 不変オブジェクトが必要なのはなぜですか? https://stackoverflow.com/a/2174170/798684 [この回答:]から言い換えます

_
. 不変オブジェクトは多くの場合最適化できます
. Pythonでは、イミュータブルのみがハッシュ可能です(そしてハッシュ可能オブジェクトのみがハッシュ可能です
セットのメンバー、または辞書のキーになります)。
_

このプロパティを比較すると、リストとタプルは「最も近い」2つのデータ型のように見えます。 高レベルでは、タプルはリストの不変の「フリーズフレーム」バージョンです。 これは、リストを変更するためにリストをコピーする必要がないため、時間の経過とともに変化するデータセットには役立ちますが、辞書キー(不変型である必要があります)などには便利です。

順序付け(および抽象データ型に関する注意)

辞書は、セットのように、固有の概念的な順序を持ちません。 これは、順序があるリストとタプルとは対照的です。 dictまたはset内の項目の順序は、プログラマーから* abstracted *離れています。つまり、 `for k in mydata`ループで要素AがBの前に来る場合、依存するべきではありません(通常は依存できません) `mydata`に変更を加え始めると、AはBの前になります。

  • 順序を維持: list、` tuple`
    +順不同: dict、` set`

技術的には、 mydata`を2回連続で繰り返す場合、同じ順序になりますが、これはPythonの仕組みの便利な機能であり、実際には set` * abstractデータ型*(データ型の数学的定義)。 ただし、リストとタプル、特に不変のタプルは順序を保証します。

繰り返したときに見えるもの(アヒルのように歩く場合)

  • 「要素」ごとに1つの「アイテム」: set、` list`、 tuple
    +「要素」ごとに2つの「アイテム」: dict

ここでは、辞書の不変の類似物として、各要素の名前と値の両方を持つ名前付きタプルを見ることができると思います。 ただし、これは微々たる比較です。名前付きタプルで辞書のみのメソッドを使用しようとする場合、またはその逆の場合、ダックタイピングが問題を引き起こすことに留意してください。

質問への直接回答

_
辞書は、特定の一意性制約を持つタプルの単なるリストではありませんか?
_

いいえ、いくつかの違いがあります。 辞書には固有の順序がありません。順序はリストと異なります。

また、辞書には各「要素」のキーと値があります。 一方、タプルは任意の数の要素を持つことができますが、それぞれに値のみがあります。

キーはセットのように機能する辞書の仕組みにより、キーがある場合は一定の時間で値を検索できます。 タプル(ここではペア)のリストでは、キーが見つかるまでリストを反復処理する必要があります。つまり、リスト内の要素の数で検索が線形になります。

ただし、最も重要なことは、辞書項目は変更できますが、タプルは変更できないことです。

_
リストは、異なる種類の一意性制約を持つ単なるセットではありませんか?
_

繰り返しますが、リストには固有の順序がありますが、セットには固有の順序はありません。 これにより、スタックやキューなど、アイテムを追加した順序を覚えておきたいものを表すのに、リストがより便利になります。 セットはそのような保証を提供しません。 ただし、それらは一定の時間でメンバーシップのルックアップを実行できるという利点を提供しますが、リストには線形の時間がかかります。

_
現在、名前付きタプルがあります-特別な場合の辞書のように感じ始めています。 順序付けられた辞書があります-リストのように感じ始めています。 そして、注文したセットのレシピを見ました。 私はこれがどんどん進んでいくのを想像することができます…​ 一意のリストなどはどうですか
_

ある程度、あなたに同意します。 ただし、データ構造ライブラリは、すでに確立されているデータ構造の一般的なユースケースをサポートするのに役立ちます。 これにより、プログラマーが標準構造のカスタム拡張を考え出そうとして時間を浪費することを防ぎます。 手に負えず、各ソリューションに独自の有用性が見られる限り、棚に車輪を置いておくとよいので、それを再発明する必要はありません。

良い例は、Counter()クラスです。 この専門の辞書は、私が数えるよりも何度も使用しており(badoom-tshhhhh!)、カスタムソリューションをコーディングする手間を省きました。 むしろ、カスタムデータ構造フォルダー内にあり、年に1、2回しか使用されないものよりも、コミュニティが適切なpythonベストプラクティスの開発と維持を支援しているソリューションが必要です。

14


これらのデータ型はすべて異なる目的に使用され、理想的な世界ではそれらをさらに統合できる可能性があります。 ただし、現実の世界では、基本的なコレクションの_効率的な実装が必要です。 順序付けは実行時のペナルティを追加します。

名前付きタプルは主にstat()などのインターフェースをより使いやすくするのに役立ち、SQL行セットを処理する際にも便利です。

あなたが探している大きな統一は、実際にはさまざまなアクセスプロトコル(getitem、getattr、iter、…​)の形であり、これらのタイプは意図した目的に合わせて一致します。

14


まず、Python 2ではOrdered DictionariesとNamed Tuplesが導入されましたが、それは重要です。

あなたが本当に興味を持っているなら、あなたはすでにそれらを読んでいただろうので、私はドキュメントであなたを指しません。

コレクション型の最初の違いは、可変性です。 tuple`と frozenset`は不変の型です。 これは、「list」や「set」よりも効率的であることを意味します。

ランダムにまたは順番にアクセスできるが、主に最後に変更されるものが必要な場合は、「リスト」が必要です。 最初に変更できるものが必要な場合は、「deque」が必要です。

ケーキを持って食べることもできません。追加する機能によって速度が低下します。

「dict」と「set」は「lists」と「tuples」とは根本的に異なります。 それらはキーのハッシュを保存し、アイテムが非常に迅速にそれらの中にあるかどうかを確認できますが、キーはハッシュ可能である必要があります。 リンクされたリストまたは配列では、同じメンバーシップのテスト速度は得られません。

OrderedDict`と NamedTuple`に到達するとき、CではなくPythonに実装されている組み込み型のサブクラスについて話していることになります。 これらは、_インポートする必要がある標準ライブラリの他のコードと同様に、特別な場合に使用します。 名前空間を乱雑にすることはありませんが、必要なときに持っておくと便利です。

これらの日のうちの1つ、あなたはコーディングするでしょう、そして、あなたは言うでしょう、「男、今私は彼らが意味することを「正確に」知っています。 set`はこれに必要な_just_であり、Python言語の一部であることがとてもうれしいです! リストを使用しなければならなかった場合、それは*永遠*になります。」それは、これらの異なるタイプが存在する理由を理解するときです。

2


辞書はキーによってインデックス付けされます(実際、ハッシュマップです)。タプルの一般的なリストはありません。 インデックスを自由に追加できるリレーションとして両方を実装する必要があると主張するかもしれませんが、実際には、一般的なユースケース向けに最適化された型を使用すると、より便利で効率的です。

多くの人々がより基本的なデータ型を使用してそれらを実装するのに十分なほど一般的であるため、新しい特殊なコレクションが追加されます。 また、Pythonが完全に汎用的な構成を提供した場合、「リレーションを使用してセットを実装する方法」などを尋ねる多くの人々がいます。

(ところで、私は数学またはDBの意味で関係を使用しています)

1


これらの特殊なコレクションタイプはすべて、リスト、タプル、辞書、セットの「標準」データタイプでは適切または効率的に提供されない特定の機能を提供します。

たとえば、一意のアイテムのコレクションが必要な場合があり、それらのアイテムの出現順序を保持する必要もあります。 メンバーシップを追跡するためのセットと順序を追跡するためのリストを使用してこれを行うことができますが、ソリューションはおそらく、順序付けされたセットなど、この目的のために設計された特殊なデータ構造よりも遅く、より多くのメモリを必要とします。

基本的なデータ型の組み合わせまたはバリエーションとして表示されるこれらの追加のデータ型は、基本的なデータ型によって残された機能のギャップを実際に埋めます。 実用的な観点から、Pythonのコアまたは標準ライブラリがこれらのデータ型を提供しなかった場合、それらを必要とする人は誰でも独自の非効率的なバージョンを発明するでしょう。 基本的な型よりも使用頻度は低いですが、標準的な実装を提供する価値があるようにするのに十分です。

1


Pythonで最も気に入っているものの1つは敏a性です。 そして、多くの機能的で効果的で使用可能なコレクションタイプがそれを私に与えてくれます。

そして、これを行う方法はまだ1つあります-それぞれのタイプは独自の仕事をします。

0


一般に、データ構造(言語に依存しない)の世界は、リスト、ツリー、ハッシュテーブル、グラフなどのいくつかの小さな基本構造に要約できます。 およびそのバリアントと組み合わせ。 それぞれには、使用と実装の観点から独自の特定の目的があります。

実際に辞書を指定しなくても、特定の一意性制約を持つタプルのリストに辞書を減らすようなことはできないと思います。 辞書には特定の目的(キー/値のルックアップ)があり、データ構造の実装は一般にこれらのニーズに合わせて調整されます。 セットは多くの点で辞書に似ていますが、セットに対する特定の操作は、辞書では意味がありません(結合、分離など)。

これは、一方向に物事を行うという「Zen of Python」に違反しているとは思いません。 ソートされた辞書を使用して、ソートされた部分を使用せずに辞書の機能を実行できますが、Occamのカミソリに違反し、パフォーマンスが低下する可能性があります。 これは、Perlのように構文的に異なる方法で実行できることとは異なると考えています。

0


_
PythonのZenは、「それを行うには明らかな方法が1つ、できれば1つだけあるべきだ」と言っています。 専門的なコレクションの種類が豊富にあることは、このPythonの教訓と矛盾しているように思えます。
_

リモートではありません。 ここで行われているいくつかの異なることがあります。 仕事に適したツールを選択します。 これらのコンテナはすべて、数十年前に試行され、テストされ、真のCSコンセプトに基づいてモデル化されています。

辞書はタプルのようなものではありません。キーと値の検索用に最適化されています。 タプルも不変であり、リストと区別します(「凍結リスト」のようなものと考えることができます)。 辞書をリストに変換したり、リストを変換したりする場合、ほぼ間違いなく何か間違ったことをしていることになります。例が役立ちます。

名前付きタプルは便宜上存在し、実際には辞書ではなく単純なクラスを置き換えることを目的としています。 順序付けられた辞書は、物事が辞書に追加された順序を覚えておくためのちょっとしたラッピングです。 また、3.xでも新しいものはありません(ただし、より優れた言語サポートがあるかもしれませんが、私は見ていません)。

0


タイトルとURLをコピーしました