私は反復可能なオブジェクト内のすべての要素を互いに組み合わせて比較したいと思います。以下の再現可能な例は単純なリストの機能を模倣していますが、私の問題を示しています。この例では、["A"、 "B"、 "C"、 "D"]のリストで、次の16行の出力を得たいと思います。 100項目のリストは、100 * 100 = 10,000行を生成します。どのようにして、同時に1つのpython iterableに複数のイテレータを持たせることができますか?
A A True
A B False
A C False
... 10 more lines ...
D B False
D C False
D D True
次のコードは、ジョブを実行する必要があります。
class C():
def __init__(self):
self.stuff = ["A","B","C","D"]
def __iter__(self):
self.idx = 0
return self
def __next__(self):
self.idx += 1
if self.idx > len(self.stuff):
raise StopIteration
else:
return self.stuff[self.idx - 1]
thing = C()
for x in thing:
for y in thing:
print(x, y, x==y)
しかし、Y-ループを終えた後、X-ループはそれが反復可能で最初の項目のみを使用していますにもかかわらず、あまりにも、行われているようです。多くの検索後
A A True
A B False
A C False
A D False
、私は最終的にitertools.teeが私に同じデータ上の2つの独立したイテレータできるようになることを期待して、次のコードを試してみました:
import itertools
thing = C()
thing_one, thing_two = itertools.tee(thing)
for x in thing_one:
for y in thing_two:
print(x, y, x==y)
をしかし、私は以前と同じ出力を得ました。
これが表す現実世界のオブジェクトは、さまざまな数のファイルとサブディレクトリを持つディレクトリとファイル構造のモデルであり、ツリーのさまざまな深さにあります。これは、この例のように、何千ものメンバーへのネストされたリンクを持っており、一度正しく繰り返します。しかし、それは、比較のために必要なときにオンザフライで多くの内部オブジェクト内で高価な処理を実行するため、反復処理を行う前に完全なコピーを作成しなければならない場合、ワークロードが倍増することになります。可能であれば、複数のイテレーターを使用して、すべてのデータを含む単一のオブジェクトを指し示したいと思います。
の回答の編集:質問のコードの重要な欠陥は、すべての答えで指摘し、独立して、複数の発信者を扱うことができない単一の内部self.idx変数です。受け入れられた答えは私の実際のクラス(この再現可能な例ではあまり単純化されていません)に最適です。もう一つの答えはここに示したリストのような単純なデータ構造のシンプルで洗練されたソリューションです。
そのようなiterableを書くよう教えてくれたソースは、使用を中止してください。 – user2357112
オブジェクトはインデックス可能ですか?それは '__len__'メソッドを持っていますか? –
これは基本的にネストされたディレクトリとファイル構造を表しているので、複数のレベルでは、その中に単一のインデックスはありません。しかし、私はノードの総数を持っているので、簡単に__len__を書くことができます。 – mightypile