python使用any()和all()来检查列表是否包含一组值或另一组

时间:2013-10-06 17:40:59

标签: python list

我的代码是针对Tic Tac Toe游戏并检查绘制状态,但我认为这个问题在一般意义上可能更有用。

我有一个代表董事会的清单,它看起来像这样:

board = [1,2,3,4,5,6,7,8,9]

当一个玩家移动时,他们移动的int被替换为他们的标记('x'或'o'),我已经有检查以寻找获胜状态,我不能做的是检查对于绘制状态,其中没有列表值是整数但是尚未设置获胜状态。

到目前为止我的代码:

if any(board) != playerOne or any(board) != playerTwo:
    print 'continue'
elif all(board) == playerOne or playerTwo:
    print 'Draw'

if语句有效,elif没有,我认为问题是我的'或'运算符,我要检查的是:如果棋盘上的每个项目都是playerOne标记或者playerTwo标记,如果我在哪里制作代码:

elif all(board) == playerOne or all(board) == playerTwo:

我会检查电路板上的每个位置是否为playerOne或者电路板上的每个位置都是playerTwo,它不会是。

那么如何通过playerOne标记和playerTwo标记的组合来检查棋盘是否被占用?

1 个答案:

答案 0 :(得分:50)

一般来说:

allany是需要迭代并返回True的函数,如果

  • all()的情况下,迭代中没有值是假的;
  • any()的情况下,至少有一个值是真实的。

虚假价值是False时编辑为bool()的任何内容。

True - 编辑时,任何变成bool()的任何内容都会被提升。


在您的特定代码示例中

你误解了这些功能的工作原理。因此,以下内容完全不符合您的想法:

if any(foobars) == big_foobar:

...因为any(foobars)首先要评估为TrueFalse,然后将该布尔值与big_foobar进行比较,这通常会给你False(除非big_foobar恰好是相同的布尔值)。

注意:迭代可以是一个列表,但它也可以是生成器/生成器表达式(≈懒惰评估/生成列表)或任何其他迭代器。

您想要的是:

if any(x == big_foobar for x in foobars):

基本上首先为foobars中的每个项构造一个产生一系列布尔值的迭代,它将项目与big_foobar进行比较,并将结果布尔值发送到结果序列:

tmp = (x == big_foobar for x in foobars)

然后any遍历tmp中的所有项目,并在找到第一个True项目后立即返回True。就好像你做了以下事情:

foobars = ['big', 'small', 'medium', 'nice', 'ugly']
big_foobar = 'big'
any(['big' == big_foobar, 'small' == big_foobar, 'medium' == big_foobar, ...])

注意:正如DSM指出的那样,any(x == y for x in xs)相当于y in xs,但后者更易读,编写速度更快,运行速度更快。

一些例子:

any(x > 5 for x in range(4))  # => False
all(isinstance(x, int) for x in range(10))  # => True
any(x == 'Erik' for x in ['Erik', 'John', 'Jane', 'Jim'])  # => True
all([True, True, True, False, True])  # => False

我强烈建议您只使用anyall在Python shell上使用各种输入,或者更好地在IPython shell上使用,以了解其工作原理你继续写实际的代码。

另请参阅:http://docs.python.org/2/library/functions.html#all