len(list)^2
ネストされた 2 つのループを使用して、最速の方法で単一のリストを解析し、比較を回避し、グループ内の重複ファイルを回避する方法についてのアドバイスを探しています。
より正確には、「ファイル」オブジェクトのリストがあり、それぞれにタイムスタンプがあります。ファイルをタイムスタンプと時間オフセットでグループ化したいと考えています。元。ファイル X から始めて、timestamp < (timestamp(x) + offset)
.
このために、私はしました:
for file_a in list:
temp_group = group()
temp_group.add(file_a)
list.remove(file_a)
for file_b in list:
if (file_b.timestamp < (file_a.timestamp + offset)):
temp_group.add(file_b)
list.remove(file_b)
groups.add(temp_group)
(わかりました、コードはもっと複雑ですが、これが主なアイデアです)
ループ中にリストを変更しているため、これは明らかに機能しません。奇妙なことが起こります:)
ループには「リスト」のコピーを使用する必要があると思いましたが、これも機能しません。
for file_a in list[:]:
temp_group = group()
temp_group.add(file_a)
list.remove(file_a)
for file_b in list[:]:
if (file_b.timestamp < (file_a.timestamp + offset)):
temp_group.add(file_b)
list.remove(file_b)
groups.add(temp_group)
まあ..リストから要素を削除せずにこれを行うことができることはわかっていますが、すでに「処理済み」のものをマークする必要があり、毎回それらをチェックする必要があります-これは速度のペナルティです.
これを最速/最良の方法で行う方法について誰かアドバイスをもらえますか?
ありがとうございました、
アレックス
編集:質問に正確に答えない別の解決策を見つけましたが、それは私が実際に必要としていたものです(そのように質問するのは私の間違いです)。Python でリストのループに関連する問題を探している人に役立つ可能性があるため、ここに投稿しています。
これは最速ではないかもしれませんが (リストの「パス」の数を考慮すると)、理解して実装するのは非常に簡単で、リストをソートする必要はありません。
並べ替えを避ける理由は、もう少し時間がかかる可能性があることと、グループの最初のセットを作成した後、それらのいくつかが「ロック」され、ロックされていないグループが「解消」され、異なる時間オフセット。(また、グループを解散すると、ファイルの順序が変更される可能性があり、再度並べ替えが必要になります)。
とにかく、解決策はループインデックスを自分で制御することでした。リストからファイルを削除すると、インデックスの増加をスキップします (例: インデックス "3" を削除すると、以前のインデックス "4" は "3" になり、ループ カウンターを増加させたくありません。私はそれをスキップします)。その反復でアイテムを削除しない場合、インデックスは通常どおり増加します。コードは次のとおりです(いくつかの追加機能があります。「バケット」のものはすべて無視してください):
def regroup(self, time_offset):
#create list of files to be used for regrouping
regroup_files_list = []
if len(self.groups) == 0:
#on first 'regroup', we start with a copy of jpeg_list, so that we do not change it further on
regroup_files_list = copy.copy(self.jpeg_list)
else:
i = 0
while True:
try:
group = self.groups[i]
except IndexError:
break
if group.is_locked == False:
regroup_files_list.extend(group)
self.groups.remove(group)
continue
else:
i += 1
bucket_group = FilesGroup()
bucket_group.name = c_bucket_group_name
while len(regroup_files_list) > 0: #we create groups until there are no files left
file_a = regroup_files_list[0]
regroup_files_list.remove(file_a)
temp_group = FilesGroup()
temp_group.start_time = file_a._iso_time
temp_group.add(file_a)
#manually manage the list index when iterating for file_b, because we're removing files
i = 0
while True:
try:
file_b = regroup_files_list[i]
except IndexError:
break
timediff = file_a._iso_time - file_b._iso_time
if timediff.days < 0 or timediff.seconds < 0:
timediff = file_b._iso_time - file_a._iso_time
if timediff < time_offset:
temp_group.add(file_b)
regroup_files_list.remove(file_b)
continue # :D we reuse the old position, because all elements were shifted to the left
else:
i += 1 #the index is increased normally
self.groups.append(temp_group)
#move files to the bucket group, if the temp group is too small
if c_bucket_group_enabled == True:
if len(temp_group) < c_bucket_group_min_count:
for file in temp_group:
bucket_group.add(file)
temp_group.remove(file)
else:
self.groups.append(temp_group)
if len(bucket_group) > 0:
self.groups.append(bucket_group)