インデックスのリストを使用して別のリストから削除すると、インデックスが範囲外のエラーになります-なぜですか?

bjk116

2つのリストを比較し、一致する場合は最初の重複インスタンスを削除してから次に進みます。これらのリスト間には重複がたくさんあることを知っているので、どちらの側にインスタンスが多いかを確認する必要があるため、リスト内包表記などを使用することはできません。基本的には、両方のリストから共有要素を差し引くように設定しています。

これが私のコードです:

toDelFromrbIndex = []
toDelFromabIndex = []
for rbIndex, (barcode, timestamp, prepack, workorder) in enumerate(restoredBottles):
    for abIndex, (idx, bcode, tstamp, tableName) in enumerate(allBottles):
         if barcode==bcode and timestamp == tstamp:
             #Remove from both lists
             toDelFromrbIndex.append(rbIndex)
             toDelFromabIndex.append(abIndex)

 for index in toDelFromrbIndex:
     del restoredBottles[index]

 for index in toDelFromabIndex:
     del allBottles[index]

これ以前は、「toDelFromrbIdnex.append(rbIndex)」がある場所でそれらを削除していましたが、繰り返しが混乱し、アイテムがスキップされる可能性があることに気付きました。したがって、最初にインデックスを保存してから、後で両方のリストからすべてを削除します。

しかし、これfor index in toDelFromrbIdnex: del restoredBottles[index]は私にindex out of rangeエラーを与えています、なぜですか?

Martijn Pieters

インデックスを最小から最大に削除しています。削除するたびに、削除されたインデックスの右側に要素が1ステップ下に移動するため、インデックスNにあったものはN-1に移動します。

最終的に、削除しようとしている最後のインデックスがリストの外側を指している可能性があります。以下もスローしIndexErrorます:

foo = [17, 42]
for index in (0, 1):
    del foo[index]

最初に17インデックスで削除するため0です。最初の要素を削除する42と、はインデックスの要素になり、0インデックス1にはもう何もありません。

最初最も高いインデックスを削除する必要があるため、インデックスを逆に処理します

 for index in reversed(toDelFromrbIdnex):
     del restoredBottles[index]

 for index in sorted(toDelFromabIdnex, reverse=True):
     del allBottles[index]

toDelFromabIndnex任意の順序でIDを追加してしまう可能性があるため、並べ替えました。

追記:現在、「ボトル」のマッチングは非常に非効率的です。ネストされたループを使用しているため、N個のrestoredBottlesエントリとM個のエントリに対してallBottlesO(NM)テストを実行しています。どちらかのリストが大きくなると、実行時間が2次関数的に増加します。たとえば、N = 100およびM = 1000の場合、100.000の比較を行い、N = 200の場合は200.000の比較になるか、Mを5000に変更して500.000の比較を行う必要があります。

中間辞書を使用する場合は、これをO(N + M)ステップに減らすことができます。

# mapping from barcode and timestamp, to index in restoredBottles
bcts_idx = {}
for i, (bc, ts, *_) in enumerate(restoredBottles)
    bcts_idx.setdefault((bc, ts), []).append(i)

toDelFromrbIndex = []
toDelFromabIndex = []
for abIndex, (idx, bcode, tstamp, tableName) in enumerate(allBottles):
    for rbIndex in bcts_idx.get((bcode, tstamp), ()):
        # Remove from both lists
        toDelFromrbIndex.append(rbIndex)
        toDelFromabIndex.append(abIndex)

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ