有一个列表,其中包含许多子列表,每个子列表包含 3 个元素,例如:
my_list = [["a", "b", 0], ["c", "d", 0], ["e", "f", 0], .....]
每个子列表的最后一个元素是一种标志,每个子列表的初始值为 0。随着算法的进展,我想检查该标志是否至少有一个元素为 0。目前我使用 while 循环,如下所示:
def check(list_): for item in list_: if item[2] == 0: return True return False
只要满足该条件,整个算法就会循环,并在每次迭代中设置一些标志:
while check(my_list): for item in my_list: if condition: item[2] = 1 else: do_sth()
因为在迭代列表时从列表中删除元素会导致问题,所以我使用这些标志来跟踪已经处理的元素。
我怎样才能简化或加快代码?
这里最好的答案是使用all(),这是这种情况的内置函数。我们将其与生成器表达式结合使用,以干净高效地产生您想要的结果。例如:
all()
>>> items = [[1, 2, 0], [1, 2, 0], [1, 2, 0]] >>> all(flag == 0 for (_, _, flag) in items) True >>> items = [[1, 2, 0], [1, 2, 1], [1, 2, 0]] >>> all(flag == 0 for (_, _, flag) in items) False
请注意,all(flag == 0 for (_, _, flag) in items)直接等同于all(item[2] == 0 for item in items),只是在这种情况下读起来更舒服一些。
all(flag == 0 for (_, _, flag) in items)
all(item[2] == 0 for item in items)
对于过滤器示例,有一个列表推导(当然,您可以在适当的情况下使用生成器表达式):
>>> [x for x in items if x[2] == 0] [[1, 2, 0], [1, 2, 0]]
如果您想检查至少一个元素是否为 0,那么更好的选择是使用any()更易读的方法:
any()
>>> any(flag == 0 for (_, _, flag) in items) True