我有一个包含20000个列表的列表。我使用每个列表的第3个元素作为标志。我想在这个列表上做一些操作,只要至少有一个元素的标志是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
循环中读取所有项,并且它会消耗大量时间!你有什么建议吗?
答案 0 :(得分:321)
这里最好的答案是使用all()
,这是这种情况的内置。我们将其与generator expression结合起来,以便干净有效地生成您想要的结果。例如:
>>> items = [[1, 2, 0], [1, 2, 0], [1, 2, 0]]
>>> all(item[2] == 0 for item in items)
True
>>> items = [[1, 2, 0], [1, 2, 1], [1, 2, 0]]
>>> all(item[2] == 0 for item in items)
False
并且,对于他的过滤器示例,列表理解:
>>> [x for x in items if x[2] == 0]
[[1, 2, 0], [1, 2, 0]]
如果你想检查至少一个元素是0,更好的选择是使用更可读的any()
:
>>> any(item[2] == 0 for item in items)
True
答案 1 :(得分:7)
你可以像这样使用itertools,一旦满足条件就会停止你的语句。相反的方法将会失败
for x in itertools.takewhile(lambda x: x[2] == 0, list)
print x
答案 2 :(得分:6)
如果您想检查列表中的任何项目是否违反条件,请使用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)
答案 3 :(得分:0)
这种方式比使用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
答案 4 :(得分:-1)
使用itertools.ifilter
的另一种方法。这检查了真实性和过程
(使用lambda
)
样本 -
for x in itertools.ifilter(lambda x: x[2] == 0, my_list):
print x