Python itertools-takewhile():多个谓词

时间:2015-12-09 19:31:46

标签: python python-3.x

假设一个生成器逐个产生以下元组(从左到右)

(1, 2, 3), (2, 5, 6), (3, 7, 10), (4, 5, 11), (3, 5, 15), (4, 5, 9), (4, 6, 12)
...

并假设只要谓词为真,我就想迭代。让谓词为sum(yielded_value) < 20。然后迭代器将停靠(3, 5, 15)。我可以这样做,比如说:

list(itertools.takewhile(lambda x: sum(x) < 20, some_generator()))

问题,如何用两个谓词编写类似的表达式?假设我想:

list(itertools.takewhile(lambda x: sum(x) < 20 and first_value_of_tuple > 3, some_generator()))

(在这种情况下,停靠(4, 6, 12)。)

3 个答案:

答案 0 :(得分:7)

您可以使用索引访问每个元组的元素。

list(itertools.takewhile(lambda x: sum(x) < 20 and x[0] > 3, some_generator()))

答案 1 :(得分:2)

由于itertools中的所有内容都被延迟迭代,并且您使用and作为两个谓词,因此您只需使用两个takewhile迭代器即可。有时我发现这比将谓词放在单个谓词函数或lambda中更具可读性:

lessthan20 = itertools.takewhile(lambda x: sum(x) < 20, some_generator())
greaterthan3 = itertools.takewhile(lambda x: x[0] > 3, lessthan20)
list(greaterthan3)

如果您需要在将来添加更多谓词,它也会使您不会拥有一个巨大的单行内容。

答案 2 :(得分:1)

如果你有其他谓词并且需要访问元组的所有元素,你也可以在lambda函数中解压缩它们:

list(itertools.takewhile(lambda (x, y, z): x+y+z < 20 and x > 3 and y < 7 and z > 1, some_generator()))

这也断言你的所有元组都有3个长度。如果你得到一个有4个值的元组,它就会很难,而不是继续静默。显然只在某些情况下有用。