我有一个set,setOfManyElements,它包含n个元素。我需要遍历所有这些元素并在S的每个元素上运行一个函数:
for s in setOfManyElements:
elementsFound=EvilFunction(s)
setOfManyElements|=elementsFound
EvilFunction(s)返回它找到的元素集。其中一些已经在S中,一些将是新的,一些将在S中,并且已经过测试。
问题是每次我运行EvilFunction时,S都会扩展(直到最大设置,此时它将停止增长)。所以我基本上在不断增长的集合上进行迭代。此外,EvilFunction需要很长时间才能进行计算,因此您不希望在同一数据上运行两次。
在Python 2.7中有没有一种有效的方法来解决这个问题?
LATE EDIT:更改变量名称以使其更易理解。谢谢你的建议
答案 0 :(得分:6)
您可以保留一组已访问过的元素,并且每次都选择一个未访问过的元素
visited = set()
todo = S
while todo:
s = todo.pop()
visited.add(s)
todo |= EvilFunction(s) - visited
答案 1 :(得分:5)
我建议使用6502的增量版本方法:
seen = set(initial_items)
active = set(initial_items)
while active:
next_active = set()
for item in active:
for result in evil_func(item):
if result not in seen:
seen.add(result)
next_active.add(result)
active = next_active
这只会访问每个项目一次,完成后seen
包含所有访问过的项目。
进一步研究:这是一个广度优先的图搜索。
答案 2 :(得分:-1)
在您的场景中迭代set
是一个坏主意,因为您无法保证排序,并且迭代器不打算在修改集中使用。所以你不知道迭代器会发生什么,你也不知道新插入元素的位置
但是,使用list
和set
可能是一个好主意:
list_elements = list(set_elements)
for s in list_elements:
elementsFound=EvilFunction(s)
new_subset = elementsFound - list_elements
list_elements.extend(new_subset)
set_elements |= new_subset
修改强>
根据所有内容的大小,您甚至可以完全放弃set
for s in list_elements:
elementsFound=EvilFunction(s)
list_elements.extend(i for i in elementsFound if i not in list_elements)
但是,我不确定这个的表现。我认为你应该介绍一下。如果列表很大,那么基于set
的解决方案似乎很好 - 执行基于集合的操作很便宜。但是,对于中等大小,EvilFunction
可能足够昂贵并且无关紧要。