如何检查一个列表的所有元素是否匹配一个条件?

我有一个单子,大概有20000个单子。我使用每个列表的第三个元素作为标志。我想在这个列表上做一些操作,只要至少有一个元素的标志是0,就像这样:

my_list = [["a", "b", 0], ["c", "d", 0], ["e", "f", 0], .....]

开始时,所有标志都是0。我使用一个while循环来检查是否至少有一个元素的标志为0:

def check(list_):
for item in list_:
if item[2] == 0:
return True
return False

如果check(my_list)返回True,则继续执行列表:

while check(my_list):
for item in my_list:
if condition:
item[2] = 1
else:
do_sth()

实际上,我想要删除my_list中的一个元素,因为我迭代它,但我不允许删除项目,因为我迭代它。

原来的my_list没有标记:

my_list = [["a", "b"], ["c", "d"], ["e", "f"], .....]

因为我不能在迭代时删除元素,所以我发明了这些标志。但是my_list包含许多项,并且while循环在每个for循环中读取所有这些项,这将消耗大量时间!你有什么建议吗?

468759 次浏览

你可以像这样使用itertools的takewhile,一旦满足条件,它就会停止。相反的方法将被抛弃

for x in itertools.takewhile(lambda x: x[2] == 0, list)
print x

如果你想检查列表中的任何项是否违反条件,请使用all:

if all([x[2] == 0 for x in lista]):
# Will run if all elements in the list has x[2] = 0 (use not to invert if necessary)

要移除所有不匹配的元素,使用filter

# Will remove all elements where x[2] is 0
listb = filter(lambda x: x[2] != 0, listb)

这里最好的答案是使用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),只是在这种情况下读起来更好一些。

并且,对于过滤器示例,一个列表理解式(当然,您可以在适当的地方使用生成器表达式):

>>> [x for x in items if x[2] == 0]
[[1, 2, 0], [1, 2, 0]]

如果你想检查至少有一个元素是0,更好的选择是使用any(),它更具可读性:

>>> any(flag == 0 for (_, _, flag) in items)
True

这种方式比使用all()更灵活:

my_list = [[1, 2, 0], [1, 2, 0], [1, 2, 0]]
all_zeros = False if False in [x[2] == 0 for x in my_list] else True
any_zeros = True if True in [x[2] == 0 for x in my_list] else False

或者更简洁地说:

all_zeros = not False in [x[2] == 0 for x in my_list]
any_zeros = 0 in [x[2] for x in my_list]
另一种使用itertools.ifilter的方法。这是对真实性和过程的检查 (使用lambda) < / p >

样品-

for x in itertools.ifilter(lambda x: x[2] == 0, my_list):
print x