私はその間に3つの異なる解決策を出しました。
1.共通辞書
最初のキーと値として辞書に形質転換された完全なグループタプルとして毎一意のフィールドを使用して一般的な辞書です。これはクラスを必要とせず、共通の辞書を返す関数で十分です。これは、テスト関数です:
def build_structure(data, indexes=(0,)):
result = {}
for elem in data:
for index in indexes:
result[elem[index]] = elem
return result
例のリストを使用して、返される構造体は、このようなものです:データが成長したときに、すべての値が参照されるので、
{
Banana: {key1: Banana, key2: myBanana, value1: fruit, value2: True},
myBanana: {key1: Banana, key2: myBanana, value1: fruit, value2: True},
...: {..:..},
myCar: {key1: Car, key2: myCar, value1: vehicle, value2: False},
}
これは、多くのメモリを食べません私はstructure['somekey']
と呼ぶことができ、結果を直接得ることができるので、グループ全体の辞書は使いやすいです。値を追加するのはちょうどstructure.update(structure_func(new_data))
です。実装は非常にシンプルですが、いくつかの副作用があります:検索キーを含まない(明らかに順序付けられていない)辞書を返します。検索キーなしで挿入順序を維持することを好みます。異なるキーフィールドでは、結果は上書きされます。反転軸を有するリストの
2.リスト
第二の溶液は、すべての埋め込まれたリストは、実際にグループの各々のためのフィールド値を含む元々与えられたデータから、リストのリストを使用するクラスでありますデータリスト。試験コード:
class MyStructure(object):
def __init__(self, data):
self.data = [[data[i][col] for i in range(len(data))] for col in range(len(data[0]))]
def get(self, col, data):
index = self.data[col].index(data)
return [self.data[c][index] for c in range(len(self.data)) if c!= col]
def append(self, data):
for i, v in enumerate(data):
self.data[i].append(v)
そして、最終的な構造は次のようであろう:
[[Banana, Water, Car],
[myBanana, myWater, myCar],
[fruit, liquid, vehicle],
[True, True, False]]
(単純structure.getを(使用))第一の溶液からの唯一の欠点その検索されクエリは、最初に、指定されたフィールドのlist.index()と、他のすべての検索フィールドのデータ[field_id] [index]を含みます。また、検索クエリのフィールドIDも知っておく必要があります。リストを参照して
3.辞書
第三の溶液は、リストの元のリストとforementionedリストインデックスへの参照を持つすべてのキーフィールド、辞書を含むリストを使用するクラスです。構造は次のようになります:その辞書のために取得するには、方法がどうなるフィールドIDと検索キーを与えられた:
[{
Banana: [Banana, myBanana, fruit, True],
Water: [Water, myWater, liquid, True],
[...]
},
{
myBanana: [Banana, myBanana, fruit, True],
[...]
}]
再度、検索クエリを呼び出すと、検索が発生する場を知ることが必要です他のフィールド値(指定されたキーを引いたもの)のリストを返します。また、すべての検索フィールドを検索し、一致する可能性のあるリストを返すメソッドを作成することもできます。
これは私が作ったテストクラスです:
class NewStructure(object):
def __init__(self, data):
self.data = data
self.field_dicts = []
for field in range(len(data[0])):
self.field_dicts.append({data[index][field]:item for index, item in enumerate(data)})
def get(self, column, value):
return [v for i, v in enumerate(self.field_dicts[column][value]) if i!=column]
def append(self, data):
self.data.append(data)
for index, field in enumerate(self.field_dicts):
field[data[index]] = self.data[-1]```
これは実際にははるかに複雑なソリューションですが、私はそれが他の人よりも多くの利点を持っていると思う:元のデータ構造は、これまでにも、変更されません。異なるフィールドに類似のキーがある場合主データ構造が大きくなると、主データ構造索引への参照が含まれるだけなので、辞書の実際の成長は最小限に抑えられます。与えられた例では、可能な検索フィールドとしてフィールドをすべてと使用しました。__init__
に許可された検索フィールドインデックスを追加すると、最初の2つのフィールドだけが検索フィールドになることを指定するなど、参照辞書ではない4.
私は自分のシナリオに従って解決策を選択する必要があると思います。私の場合、実際には「リアルタイム」の結果は実際には必要ありません。私は最後の解決策をとって、おそらく動的メソッドの作成を追加し、クラス名にフィールド名を必要とし、structure.get_from_key1(Banana)
のようなものを許可したいと思います。
しかし、私はプログラマーではない、私はただ楽しいためにこれを行う。誰かが他のアイデアを持っていれば、別の視点を知ることでも分かります。 :)
ありがとう!
PS:誰かがこの質問の方がより明確なタイトルを持っている場合は、編集していただければ幸いです。
おそらく名前付きタプルを使用しますか? https://docs.python.org/3/library/collections.html#collections.namedtuple –
これは私の教科書クラスのようです。 – msvalkon
@TedKleinBergman名前付きタプルを使用することはできません。なぜなら、私が書いたように、「共通」の値(最後のブールなど)を変更する必要があるからです。 – musicamante