-1

私はカスタムコンテナクラスを作成しています。構成オブジェクトはコンテナとは独立して作成され、コンテナのないメンバーまたは複数のコンテナのメンバーになることができます。すべてのオブジェクトの上にさまざまなコンテナからの効率的な削除を可能にする汎用参照

  • 反復
  • 既存のオブジェクト

コンテナはいくつかの追加作業を行うの新しいオブジェクト

  • 除去の挿入、およびその:コンテナの公開APIは、3つの操作をサポートする必要があります正確な実装が変わる可能性があります。

    実装を変更しても安定した状態になるように、このクラスにパブリックAPIを書き込むにはどうすればよいですか?

    コンテナがlistの場合、効率的な削除にはオブジェクトのインデックスの知識が必要です。オブジェクトそのものが良くないことを知っている(私は要素のコンテナ全体を検索したくない)。

    コンテナがsetの場合は、インデックスと同じものは何もありません。オブジェクト自体が必要です。

    コンテナが単独でリンクされたリストのようなものなら、削除するオブジェクトの前のオブジェクトへの参照が必要です。

    コンテナが二重リンクリストのようなものなら、オブジェクト自体への参照が必要です。

    私は除去方法に意味がないか、削除方法の外で使用する単一の引数referenceを取ることを考えています。反復では、(object,reference)のペアが生成されます。

    このデザインに問題はありますか?私が見ることができる例やデザインパターンはありますか?

    理想的には、元のobjectreferenceの両方を含み、両方のインターフェイスを示す複雑なオブジェクトを生成することが理想です。しかし、私はこれが実行可能であるとは思わない?

  • +3

    あなたの質問は何ですか?これは学問的な運動ですか?そうでない場合は、なぜ自分のリストやコンテナを実装していますか? –

    +2

    このコンテナはどのような目的を果たしますか? Pythonの組込みコレクション型では簡単にはできないことはどうしますか? –

    +0

    @Steven Rumbalskiパフォーマンスをテストしているため、実装を変更する必要があります。コンテナはis要素の特定の順序を維持します。 – max

    答えて

    0

    は、他の誰かがよりよい解決策を見つけることによって助けない限り、私がやるものだ:

    # to get __hash__ and __eq__ return id(self) 
    class Reference: 
        def __init__(self, item): 
        self.item = item 
    
    class RemovalAPI: 
        def add_removal_info(self, item, removal_info): 
        try: 
         references = item.__reference 
        except AttributeError: 
         references = item.__reference = {} 
        references[Reference(self)] = removal_info 
    
        def get_removal_info(self, item): 
        try: 
         references = item.__reference 
         self_reference = Reference(self) 
         return references[self_reference] 
    
    
    
    class Container(list, RemovalAPI): 
        def __iter__(self): 
        for i in range(len(self)): 
         item = self[i] 
         self.add_removal_info(item, i) 
         yield item 
    
        def remove(self, item): 
        removal_info = self.get_removal_info(item) 
        del self[removal_info] 
    
        def insert(self, item): 
        self.add_removal_info(item, len(self)) 
        self.append(item) 
        # do whatever post-processing I need 
        # ... 
    

    場合実装をlistから他のデータ構造に変更することを決定した場合、パブリックインターフェイスは変更されないままです。

    class Container(orderedset, RemovalAPI): 
        # inheriting __iter__, remove from parent 
        def insert(self, item): 
        self.add(item) 
        # do whatever post-processing I need 
        # ... 
    

    または

    class Container(linkedlist, RemovalAPI): 
        def __iter__(self): 
        it = super().__iter__() 
        last_item = None 
        for item in it: 
         self.add_removal_info(item, last_item) 
         yield item 
    
        def remove(self, item): 
        removal_info = self.get_removal_info(item) 
        if removal_info is None: 
         self.remove_first() 
        else: 
         self.remove_after(removal_info) 
    
        def insert(self, item): 
        self.add_removal_info(item, None) 
        self.add_to_front(item) 
        # do whatever post-processing I need 
        # ... 
    
    +0

    アイテムを複数のコンテナに入れ始めると、アイテム自体の「秘密」属性に参照を格納することが完全に中断します。あなたが必要とするのは、各コンテナがコンテナと参照の間のマッピングを個別に*保存することです。 – Ben

    +0

    ええ、ありがとう...誰かがより良いアプローチを提案したいと思っていたので、私はこれを考えなかった。私は '__reference'を' __references'に変換することができます(属性がある場合)キーは 'id(container)'であり、値は 'container'の「一般化された参照」です。 – max

    +0

    これを行う場合は、オブジェクト内のコンテナへの参照を保持する必要もあります。さもなければあなたのid値はコンテナよりも長く生き続けます(コンテナが生きている間にコンテナがゴミになった場合)、新しいコンテナが古いアドレスと同じアドレスに割り当てられる可能性は低くなります。同じid値。それは特定の割り当てパターンの下でのみ発生する非常にあいまいなバグになるので、それをデバッグしようとするとおそらく遠ざかります。 – Ben

    0

    ほとんどのコンテナタイプは、インデックスからインデックス、現在のものから次のものなど、うまく機能するような方向性を持っています。双方向性はありますが、すべてから遠いものもあります。

    インデックスを使用せずにPythonリストの値を見つけようとすると、かなり多くO(n)になります。あなたはO(n)を受け入れるか、別のタイプを使用する必要があります。

    これに気をつけることの1つは、大量のコンテナタイプから何かをすばやく削除する必要がある場合、値に「ignore_this」属性を追加することができるということです。それをtrueに設定すると、すべてのコンテナタイプが無視され始めます。見たときにコンテナタイプを削除することもできます。

    +0

    要素を見つけるには 'O(n)'になることを理解しています。したがって、私はそれを効率的にするために余分な情報を削除メソッドに渡そうとしています。私の問題は、これをどう設計するかです。 – max

    0

    だけでカプセル化しlistdict/listset、...

    は大雑把にあなたのメモリ使用量と動作時間を倍増、しかし巧妙なカプセル化は、多くの場合、ほぼすべての 問題関連ます操作 O(1)

    +0

    私が考えている容器は事前に分かっていません。私はAPIを設計しています。コンテナが 'O(1)'ルックアップをサポートするように強制することは、特定の型を強制的に強制することを意味します。それは私の目標ではありません。 – max

    +0

    さて、私はあなたの質問を理解していません。あなたが何か愚かなことをやっていない限り、すべてが大丈夫だろう。 – ch3ka

    0

    あなたは、Python 2.7以上を使用している場合はcollections.OrderedDictを見て価値があるかもしれません。ここでhttp://docs.python.org/library/collections.html#collections.OrderedDict

    +0

    ありがとうございます。私は、標準ライブラリとサードパーティの両方のPythonのすべてのコンテナ型に精通しています。私が選択した実装に依存しないAPIを用意したいだけです。 – max

    +0

    ああ、今私はあなたの質問を理解しています。あなたが概説したラフなデザインは、私にとっては妥当と思われます。私が持っているコメントだけは、コレクションの単純な反復が実際のオブジェクトを返す必要があるということです。 (ハンドル、オブジェクト)タプルを返す別のメソッドを列挙することができます。また、insertは、ユーザーがオブジェクトの削除に使用できるオブジェクトへのハンドルを戻す必要があります。 – spinlok

    関連する問題