web-dev-qa-db-ja.com

開発者はどのように、いつ、なぜ、Pythonでカスタムデータ構造を使用するのですか?

Pythonにはポインタがないため、データ構造の構築が直感的に難しくなり、組み込みの機能が非常に多いため、アマチュアとしては、既存の機能を超えて何かをいつ、なぜ、どのように作成するのかわかりません。

いつあなたはあなた自身のものを作りましたか、そしてなぜあなたはそれをしましたか?例えば。特別な種類の木など.

6

まあ、その種類は、「データ構造」と呼んでもいいかどうかに依存します。 Wikipdiaによると、データ構造は単に「データを効率的に使用できるようにコンピューターに保存および整理する特定の方法」です。したがって、クラスはデータ構造の1つの形式であり、クラスはPythonで非常に広く使用されています。しかし、この答えのために、データ構造とアルゴリズムクラス(たとえば、ツリー、リンクリスト、キュー、ハッシュなど)で何を学べるかに興味があると仮定します。

さて、Pythonの疑似コードのような構文のため、データ構造を実装するための非常に有用な言語になる可能性があります。これらの基本的な概念を理解するのに役立つ以外の目的がない場合。たとえば、リンクリストについて初めて知ったとき、それらをPythonで実装することにしました。

class node:
    def __init__(self, data = None, is_header = False):
        self.data = data
        self.next = None
    def __str__(self):
        return "|{0}| --> {1}".format(str(self.data), str(self.next))


class linked_list:
    def __init__(self):
        self.header = node("!Header!", True)

    def add_node(self, add_me):
        current_node = self.header
        while 1:
            if current_node.next == None:
            current_node.next = add_me
            break
            else:
            current_node = current_node.next    

    def print(self):
        print (str(self.header))

さて、これは完璧な例ではありませんし、リンクリストの完全に適切な実装でさえありませんが、それは何かを説明するために行きます:

Pythonの単純な構文は、データ構造を理解するのに役立ちます

もう1つの例は、その日に作成した優先キューです。

class priority_queue:
    def __init__(self):
        self.element = []
        self.priority = []

    def enqueue_with_priority(self, me, priority):
        where = 0
        for i in range(len(self.element)):
            if not priority < self.priority[i]:
            where = i
            break

        self.element.insert(where, me)
        self.priority.insert(where, priority)

    def dequeue_highest(self):
        return self.element.pop(0)

    def print(self):
        for i in self.element:
            print i

繰り返しになりますが、完璧な実装ではありませんが、Pythonでデータ構造をコーディングするもう1つの利点を示しています。

Pythonは、データ構造をプロトタイプ化して低レベルのプログラミング言語用に最適化するのに役立ちます

このコードを振り返ると、実装に欠陥があることがわかります。ただし、Pythonコードは短くて甘い傾向があります。したがって、下位レベルの言語(Cスタイルの言語など)でデータ構造を実装したい場合は、最初に迅速なPythonプロトタイプを生成し、後で最適化できます。

最後に、Pythonはデータ構造の開発に役立つと思います。

Pythonでは、開発が迅速で、ミスが許され、試してみることができます。

強く型付けされたコンパイル済み言語で、ハッシュテーブルのようなデータ構造を構築していると想像してください。通常はIDEで試してから、コンパイルして実行する必要があります。 Pythonでは、IDLE、iPython、またはPythonインタープリターをプルアップして、実際に試すことができます。試してみたいハッシュ関数を少し変更するたびに再コンパイルする必要はありません。それをインタプリタに接続するだけです。

結論として、私が言っていることは私があなたに同意することだと思います:独自のデータ構造を構築することには実用性はあまりありません(あなたが望むかもしれないほとんどのものはすでに実装され最適化されているからです)。ただし、私にとっては、(Pythonの構文が簡単なため)多くの教育上の利点と、(Pythonの制約が少ないため [〜#〜] eafp [ 〜#〜] デザイン)。

pythonは(広範囲にわたるライブラリを通じて)多くの標準データ構造を提供しますが、「データ構造」(定義上)はほとんど何でもかまいません。したがって、Pythonや、自明ではない問題を解決するために使用する他の言語では、新しいデータ構造を定義する必要があります。したがって、真面目なPython開発者が他の言語の真面目な開発者と同じようにカスタムデータ構造を作成することは、かなり議論の余地があります。

4
mjgpy3

Pythonでデータ構造を作成するには、クラスを使用します。Python(および他の参照ベースの言語)での参照は、ポインタのように機能するため、制限はありません。データ構造を実装できるようになります。

Pythonには多くのデータ構造が組み込まれています。しかし、他のさまざまな言語もそうです。 C++またはJavaの標準ライブラリのSTLを参照してください。 C++とJava=の両方で、基本的な構造のほとんどがすでに存在するため、独自のデータ構造を実装する必要もほとんどありません。

ただし、場合によっては、Pythonに組み込みがない必要があるデータ構造があります。たとえば、pythonには組み込みのツリーベースの構造がありません、またはリンクリストなど。それほど頻繁に必要になるわけではありませんが、必要なときに必要になります。

2
Winston Ewert

他の回答には、ゼロから作成された有用なデータ構造がリストされていますが、既存のデータ構造の機能を拡張することも有用です。

単純な不変データにはnamedtuplesを、単純な可変データにはSimpleNamespacesを使用したいのですが、便利な機能がありません。たとえば、SimpleNamespacesは反復を許可せず、.keys().values()または.items()を介してアクセスできません。だから、私はそのように機能を拡張します:

_from types import SimpleNamespace


class CustomNamespace(SimpleNamespace):
    """
    Adds iteration and dict-style access of keys, values and items to SimpleNamespace.
    """
    def keys(self):
        for key in self.__dict__:
            yield key

    def values(self):
        for value in self.__dict__.values():
            yield value

    def items(self):
        for key, value in self.__dict__.items():
            yield key, value

    def __iter__(self):
        return self.items()

_

これで、SimpleNamespaceのすべての通常の機能(変更可能、インラインでの作成が容易など)がすべて得られ、すべてのエントリを反復処理して.values()などを呼び出すこともできます。

0
QuantumChris