如何在循环中从Python列表中排除对象
我正在写一个程序,里面有一个循环,用来遍历一个对象的列表。在这个循环里,还有一个第二个循环,它会遍历所有对象,但会跳过第一个循环中当前的对象。这种情况会重复好几次:
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)):
# ....