【问题标题】:Using any() and all() to check if a list contains one set of values or another使用 any() 和 all() 检查列表是否包含一组值或另一个
【发布时间】:2013-10-13 06:12:11
【问题描述】:

我的代码用于井字游戏并检查平局状态,但我认为这个问题在一般意义上可能更有用。

我有一个代表棋盘的列表,它看起来像这样:

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 标记的组合占用?

【问题讨论】:

  • any()all() 确实不是这样工作的:"如果迭代的(任何/所有)元素为真,则返回 True。如果迭代为空,则返回 False 。”

标签: python list


【解决方案1】:

一般来说:

allany 是接受一些可迭代并返回 True 的函数,如果

  • all() 的情况下,iterable 中没有任何值是虚假的;
  • any() 的情况下,至少有一个值为真。

如果bool(x) == False,则值x 是虚假的。 x 的值是真实的,如果 bool(x) == True

iterable 中的任何非布尔值都可以——bool(x) 将根据以下规则映射(或强制,如果您愿意)任何 x00.0None、@987654336 @、()[]set() 和其他空集合映射到 False,其他任何东西都映射到 Truebool 的文档字符串使用术语 'true'/'false' 表示 'truthy'/'falsy',True/False 表示具体的布尔值。


在您的特定代码示例中:

您对这些函数的工作方式有一点误解。因此,以下内容完全不是您想的那样:

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。就好像你做了以下事情:

In [1]: foobars = ['big', 'small', 'medium', 'nice', 'ugly']                                        

In [2]: big_foobar = 'big'                                                                          

In [3]: any(['big' == big_foobar, 'small' == big_foobar, 'medium' == big_foobar, 'nice' == big_foobar, 'ugly' == big_foobar])        
Out[3]: True

注意:正如 DSM 指出的,any(x == y for x in xs) 等同于 y in xs,但后者更具可读性、编写速度更快、运行速度更快。

一些例子:

In [1]: any(x > 5 for x in range(4))
Out[1]: False

In [2]: all(isinstance(x, int) for x in range(10))
Out[2]: True

In [3]: any(x == 'Erik' for x in ['Erik', 'John', 'Jane', 'Jim'])
Out[3]: True

In [4]: all([True, True, True, False, True])
Out[4]: False

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

【讨论】:

  • 我认为写big_foobar in foobars而不是any(x == big_foobar for x in foobars)会更惯用。
  • 好的,所以要更改我的行:如果有(板)!= playerOne 或任何(板)!= playerTwo:会变成:如果有(x != playerOne 或 x!= playerTwo for x in board):?
  • @DSM:是的,当然,但我必须以他的用例为基础:)
  • @DasSnipez:这意味着“如果棋盘中存在不属于任何一个玩家的物品”......所以如果这就是你想要的,是的。
猜你喜欢
  • 2021-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-07
  • 1970-01-01
  • 1970-01-01
  • 2017-01-13
相关资源
最近更新 更多