【发布时间】:2010-12-07 11:27:20
【问题描述】:
我正在寻找有关如何以最快的方式解析单个列表、使用两个嵌套循环、避免进行 len(list)^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)
【问题讨论】:
标签: python performance list nested-loops