如何在循环中从Python列表中排除对象

2 投票
2 回答
3837 浏览
提问于 2025-04-18 08:30

我正在写一个程序,里面有一个循环,用来遍历一个对象的列表。在这个循环里,还有一个第二个循环,它会遍历所有对象,但会跳过第一个循环中当前的对象。这种情况会重复好几次:

for obj1 in obj_list:
    for obj2 in (obj_list except obj1):
        for obj3 in (obj_list except obj1 and obj2):
            ...

我的实际代码在这两个循环之间还做了一些其他的事情,所以我不能简单地使用 permutations() 这样的工具。我的实现方式可能是这样的:

for i1 in range(len(obj_list)):
    obj1 = obj_list[i1]
    for i2 in range(len(obj_list)-1):
        obj2 = (obj_list[:i1] + obj_list[i1 + 1:])[i2]
        ...

不过,这样写会让代码变得很乱,尤其是当我想排除多个对象时,代码会变得更加复杂。有没有一种更简洁的方法来实现这个想法,类似于第一个代码块,但又不修改原来的列表?需要注意的是,我的列表里没有重复的对象,所以不需要考虑重复的情况。

2 个回答

1

他们有一段和 permutation 函数等效的 Python 代码,你可以修改这段代码,让它接受一个函数:

def permutations(iterable, func, r=None):
    # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
    # permutations(range(3)) --> 012 021 102 120 201 210
    pool = tuple(iterable)
    n = len(pool)
    r = n if r is None else r
    if r > n:
        return
    indices = list(range(n))
    cycles = list(range(n, n-r, -1))
    yield tuple(pool[i] for i in indices[:r])
    while n:
        func()
        for i in reversed(range(r)):
            cycles[i] -= 1
            if cycles[i] == 0:
                indices[i:] = indices[i+1:] + indices[i:i+1]
                cycles[i] = n - i
            else:
                j = cycles[i]
                indices[i], indices[-j] = indices[-j], indices[i]
                yield tuple(pool[i] for i in indices[:r])
                break
        else:
            return

f = lambda: print('LOL')

list(permutations([1,2,3,4], f))

对于每一个排列,都会调用这个函数,并打印出“LOL”。输出结果是:

LOL
LOL
LOL
LOL
LOL
LOL
LOL
LOL
LOL
LOL
4

考虑一下这个:

for obj1 in obj_list:
    for obj2 in (obj for obj in obj_list if obj != obj1):
        for obj3 in (obj for obj in obj_list if obj not in (obj1, obj2)):
            # ....

你可以做一个更通用的生成器来实现你想要的功能,像这样:

def exclusion_generator(base_list, to_excludes):
    for item in base_list:
        if item not in to_excludes:
            yield item

然后可以这样使用它:

for obj1 in objs:
    for obj2 in exclusion_generator(objs, (obj1,)):
        for obj3 in exclusion_generator(objs, (obj1, obj2)):
            # ....

撰写回答