23

私がPythonを愛する理由の1つは、タプル、リスト、セット、および辞書によって提供される表現力/プログラミングの労力の削減です。リスト内包表記ととを使用したいくつかの基本的なパターンを理解するinfor、人生はとても良くなります!Pythonは素晴らしいです。

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

現在、3.xの世界では、より複雑になっています。現在、タプルという名前が付けられています。これは、特殊なケースの辞書のように感じ始めています。現在、順序付けられた辞書があり、リストのように感じ始めています。そして、注文したセットのレシピを見たところです。私はこれが続いていることを想像することができます...ユニークなリストなどはどうですか?

PythonのZenは、「それを行うための明白な方法は1つ、できれば1つだけでなければならない」と述べています。この大量の特殊なコレクションタイプは、このPythonの原則と矛盾しているように思われます。

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

4

8 に答える 8

16

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

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

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

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

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

  • 可変:dict、、listset

    不変:tuple

Pythonstringも不変の型です。なぜ不変のオブジェクトが必要なのですか?私はこの答えから言い換えます:

  1. 不変オブジェクトは多くの場合最適化できます

  2. Pythonでは、不変のものだけがハッシュ可能です(そして、ハッシュ可能なオブジェクトだけがセットのメンバー、または辞書のキーになることができます)。

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

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

セットのような辞書には、固有の概念的な順序はありません。これは、順序があるリストやタプルとは対照的です。dictまたはセット内のアイテムの順序はプログラマーから抽象化されています。つまり、要素Aがfor k in mydataループ内でBの前にある場合、開始後にAがBの前にあることに依存するべきではありません(通常は信頼できません)。に変更を加えるmydata

  • 順序を維持する:listtuple

    非順序保持:dictset

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

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

  • 「要素」ごとに1つの「アイテム」:set、、listtuple

    「要素」ごとに2つの「アイテム」:dict

ここでは、辞書の不変の類似物として、各要素の名前と値の両方を持つ名前付きタプルを見ることができると思います。ただし、これは微妙な比較です。名前付きタプルで辞書のみのメソッドを使用しようとすると、ダックタイピングで問題が発生することを覚えておいてください。その逆も同様です。

あなたの質問への直接の回答

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

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

また、ディクショナリには、各「要素」のキーと値があります。一方、タプルは任意の数の要素を持つことができますが、それぞれに値しかありません。

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

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

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

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

現在、タプルという名前が付けられています。これは、特殊なケースの辞書のように感じ始めています。現在、順序付けられた辞書があり、リストのように感じ始めています。そして、注文したセットのレシピを見たところです。私はこれが続いていることを想像することができます...ユニークなリストなどはどうですか?

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

良い例はCounter()クラスです。この特殊な辞書は、数え切れないほど何度も使用されており(badoom-tshhhhh!)、カスタムソリューションをコーディングする手間を省くことができました。カスタムデータ構造フォルダーにあり、年に1〜2回しか使用されないものよりも、コミュニティが適切なPythonのベストプラクティスを開発して維持するのに役立つソリューションが欲しいです。

于 2011-08-04T21:06:14.207 に答える
16

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

名前付きタプルは、主にstat()などのインターフェイスをより使いやすくするために使用され、SQL行セットを処理する場合にも役立ちます。

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

于 2011-08-04T21:07:44.877 に答える
2

まず、順序付き辞書と名前付きタプルがPython 2で導入されましたが、それは重要ではありません。

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

コレクションタイプ間の最初の違いは、可変性です。tuplefrozensetは不変の型です。listこれは、またはよりも効率的である可能性があることを意味しますset

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

あなたは単にあなたのケーキを持ってそれを食べることもできません-あなたが追加するすべての機能はあなたにいくらかの速度を失う原因になります。

dictタプルとsetは根本的に異なりlistsます。キーのハッシュを保存するため、アイテムがキーに含まれているかどうかをすばやく確認できますが、キーはハッシュ可能である必要があります。リンクリストまたは配列では、同じメンバーシップテスト速度は得られません。

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

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

于 2011-08-04T21:12:38.593 に答える
1

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

新しい特殊なコレクションが追加されるのは、多くの人がより基本的なデータ型を使用してそれらを実装することになるほど一般的であり、その後、車輪の再発明に関する通常の問題(無駄な労力、相互運用性の欠如など)が発生するためです。また、Pythonが完全に汎用的な構造を提供しただけの場合、「リレーションを使用してセットを実装するにはどうすればよいか」などの質問が多く寄せられます。

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

于 2011-08-04T21:01:36.403 に答える
1

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

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

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

于 2011-08-04T21:06:56.020 に答える
0

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

そして、これを行う方法はまだ1つあります。つまり、各タイプが独自の役割を果たします。

于 2011-08-04T21:05:22.037 に答える
0

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

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

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

于 2011-08-04T21:07:48.280 に答える
0

PythonのZenは、「それを行うための明白な方法は1つ、できれば1つだけでなければならない」と述べています。この大量の特殊なコレクションタイプは、このPythonの原則と矛盾しているように思われます。

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

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

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

于 2011-08-04T21:19:49.690 に答える