迭代在python中不断增长的集合

时间:2015-02-18 13:09:59

标签: python python-2.7 set iteration

我有一个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:更改变量名称以使其更易理解。谢谢你的建议

3 个答案:

答案 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是一个坏主意,因为您无法保证排序,并且迭代器不打算在修改集中使用。所以你不知道迭代器会发生什么,你也不知道新插入元素的位置

但是,使用listset可能是一个好主意:

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可能足够昂贵并且无关紧要。