2012-05-19 80 views
97

我有一个类似20000列表组成的列表。我使用每个列表的第三个元素作为标志。我想做这个名单上的一些操作,只要至少一个元素的标志是0,这是这样的:如何检查列表中的所有元素是否与条件匹配?

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

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

def check(lista): 
    for item in lista: 
     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循环中读取它们,并且它会消耗大量时间!你有什么建议吗?

+2

看起来像你的数据结构不理想您的问题。如果你再详细解释一下上下文,也许我们可以提出一些更合适的建议。 – uselpa

+0

也许你可以用'None'或'[]'代替项目,而不是删除它们。在每次内循环传递之前,使用'check()'遍历所有项目来检查整个列表是非常缓慢的方法。 – martineau

回答

211

这里最好的答案是使用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 
+0

我在使用lambda时遇到的错误,Python的全部都不接受像Haskell等人的第一个参数那样的函数。同样,我也改变了我对列表理解的回答。 :) –

+2

@HampusNilsson列表理解不同于生成器表达式。作为'all()'和'any()'短路,例如,如果我的第一个值计算为'False',all()将失败并且不检查任何更多值,返回'False'。您的示例将执行相同的操作,除非它会首先生成整个比较列表,这意味着很多处理都是空的。 –

5

您可以像这样使用itertools的时间,一旦满足条件而导致语句失败,它就会停止。如果您想检查列表中的任何项目违反了条件使用all相反的方法是dropwhile

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

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) 
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 
0

另一种使用方法itertools.ifilter。这种检查感实性和工艺 (使用lambda

的Sample-

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