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

alw*_*btc 188 python for-loop list while-loop

我有一个包含20000个列表的列表.我使用每个列表的第3个元素作为标志.我希望在此列表上执行一些操作,只要至少有一个元素的标志为0,它就像:

my_list = [["a", "b", 0], ["c", "d", 0], ["e", "f", 0], .....]
Run Code Online (Sandbox Code Playgroud)

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

def check(list_):
    for item in list_:
        if item[2] == 0:
            return True
    return False
Run Code Online (Sandbox Code Playgroud)

如果check(my_list)返回True,那么我继续处理我的列表:

while check(my_list):
    for item in my_list:
        if condition:
            item[2] = 1
        else:
            do_sth()
Run Code Online (Sandbox Code Playgroud)

实际上,当我迭代它时,我想删除my_list中的一个元素,但是当我迭代它时,我不允许删除项目.

原始的my_list没有标志:

my_list = [["a", "b"], ["c", "d"], ["e", "f"], .....]
Run Code Online (Sandbox Code Playgroud)

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

Gar*_*tty 366

这里最好的答案是使用all(),这是这种情况的内置.我们将它与生成器表达式结合起来,以产生您想要的干净和高效的结果.例如:

>>> 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
Run Code Online (Sandbox Code Playgroud)

并且,对于他的过滤器示例,列表理解:

>>> [x for x in items if x[2] == 0]
[[1, 2, 0], [1, 2, 0]]
Run Code Online (Sandbox Code Playgroud)

如果要检查至少一个元素是0,那么更好的选择是使用any()哪个更易读:

>>> any(item[2] == 0 for item in items)
True
Run Code Online (Sandbox Code Playgroud)

  • @HampusNilsson列表推导与生成器表达式不同.作为`all()`和`any()`短路,例如,如果我的第一个值计算为'False`,则`all()`将失败并且不再检查任何值,返回`False`.您的示例将执行相同的操作,但它将首先生成整个比较列表,这意味着无需进行大量处理. (3认同)
  • @CharlieParker 将其设为这样的列表理解只会使事情变慢,正如我之前的评论中所讨论的。您想使用生成器表达式(无方括号),因为这样可能会短路。 (2认同)

Hed*_*ide 7

你可以像这样使用itertools,一旦满足条件就会停止你的语句.相反的方法将会失败

for x in itertools.takewhile(lambda x: x[2] == 0, list)
    print x
Run Code Online (Sandbox Code Playgroud)


Ham*_*son 7

如果要检查列表中的任何项是否违反条件,请使用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)
Run Code Online (Sandbox Code Playgroud)

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

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

  • 您可以删除 `all(...)` 中的 `[...]`,因为它可以创建一个生成器而不是列表,这不仅可以为您节省两个字符,还可以节省内存和时间。通过使用生成器,一次只计算一个项目(以前的结果将被删除,因为不再使用),如果其中任何一个结果为“假”,生成器将停止计算其余的。 (2认同)
  • python3的注意事项;`filter()` 返回一个可迭代对象,而不是一个列表。因此,该行将是 `listb = list(filter(lamba x: x[2] != 0, listb))` (2认同)