从集合中迭代和删除-是否可以?

时间:2019-04-12 00:52:19

标签: python

我没有想要查看的特定代码;但是,我确实有一个问题,我似乎无法获得一个清晰明确的答案。

这是问题:如果有一个集合,可以在for循环中对其进行迭代。当我遍历它时,我可以使用.remove()删除特定的数字,还是必须先将我的集合转换为列表?如果是这样,为什么我必须先将其转换?

3 个答案:

答案 0 :(得分:1)

在两种情况下,都应避免迭代和删除列表或集合中的项目。修改要迭代的内容不是一个好主意,因为这样可以获得意外的结果。例如,让我们以set

开始
numbers_set = {1,2,3,4,5,6}
for num in numbers_set:
    numbers_set.remove(num)
print(numbers_set)

我们尝试遍历并删除每个数字,但出现此错误。

Traceback (most recent call last):
  File ".\test.py", line 2, in <module>
    for num in numbers_set:
RuntimeError: Set changed size during iteration

现在您提到“我必须先将我的电视机转换为列表吗?”。好吧,让我们测试一下。

numbers_list = [1,2,3,4,5,6]
for num in numbers_list:
    print(num)
    numbers_list.remove(num)
print(numbers_list)

这是结果:

[2, 4, 6]

我们希望列表为空,但它给了我们这个结果。无论您是尝试遍历列表还是集合并删除项目,通常都不是一个好主意。

答案 1 :(得分:1)

这就是我要这样做的方式:

myset = ...
newset = set()
while myset:
    v = myset.pop()
    if not do_i_want_to_delete_this_value(v):
        newset.add(v)
myset = newset

列表理解也将起作用:

myset = set([x for x in myset if not do_i_want_to_delete_this_value(x)])

但是,如果您要在迭代时做其他事情,并且不想将所有逻辑包装在单个函数调用中,则这会变得很混乱。这样做没错。

myset = set([x for x in myset if process_element(x)])

process_element()只需返回True / False即可确定是否应从集合中删除该元素。

答案 2 :(得分:1)

@nathancy已经很好地解释了为什么在迭代过程中删除不起作用,但是我想提出一个替代方案:与其在迭代的同时进行删除,不如将其作为第二阶段。因此,您改为:

  1. 遍历集合以决定要删除的内容,并分别存储要删除的内容的集合。
  2. 遍历要删除的集合,然后从原始集合中删除每个项目。

例如:

def should_be_deleted(num):
    return num % 2 == 0

my_set = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
to_delete = []
for value in my_set:
    if should_be_deleted(value):
        to_delete.append(value)

for value in to_delete:
    my_set.remove(value)

print(my_set)

打印:

set([1, 3, 5, 7, 9])

可以使用相同的模式从任何集合中删除-不仅可以删除set,还可以删除listdict等。

相关问题