有没有编写此代码的较短方法?

时间:2019-08-06 06:49:03

标签: python

我想知道下面是否有更短的编写代码的方式。

if l[0] == g and l[1] == g and l[2] == g or l[3] == g and l[4] == g and l[5] == g or l[6] == g and l[7] == g and l[8] == g or l[0] == g and l[3] == g and l[6] == g or l[1] == g and l[4] == g and l[7] == g or l[2] == g and l[5] == g and l[8] == g or l[0] == g and l[4] == g and l[8] == g or l[2] == g and l[4] == g and l[6] == g:

我已经尝试过:

if (l[0] and l[1] and l[2] or l[3] and l[4] and l[5] or l[6] and l[7] and l[8] or l[0] and l[3] and l[6] or l[1] and l[4] and l[7] or l[2] and l[5] and l[8] or l[0] and l[4] and l[8] or l[2] and l[4] and l[6]) == g:

这:

if g in (l[0] and l[1] and l[2] or l[3] and l[4] and l[5] or l[6] and l[7] and l[8] or l[0] and l[3] and l[6] or l[1] and l[4] and l[7] or l[2] and l[5] and l[8] or l[0] and l[4] and l[8] or l[2] and l[4] and l[6]):

但是它不起作用。

2 个答案:

答案 0 :(得分:5)

如果我理解正确,那么您正在检查具有预定义索引的子列表是否包含值g。首先,您可以提取索引组:

indices = [
    (0, 1, 2),
    (3, 4, 5),
    ... # etc
    (2, 4, 6)
]

然后循环检查它们:

for ix in indices:
    if all(l[i] == g for i in ix):
        return True
return False

如果您实际上需要检查所有 三元组,则可以使用itertools.combinations而不是对索引进行硬编码:

for sub in itertools.combinations(l, 3):
    if all(x == g for x in sub):
        return True
return False

答案 1 :(得分:0)

修改后的if-测试

l[0] and l[1] and l[2]

是您想要组合测试的真值,但是此代码的作用是and将您的3个值放在一起,扔掉其中2个。此转换发生在==之前。如果l的前3个元素分别是1、3、5,那么您的and表达式的结果将是5,这就是与g进行比较的结果(不是某些然后可以与==一起使用1、3和5的叠加)。

您的代码看起来好像已经简化为一个简单列表的数据结构,并且由于数据不再反映其意图,因此if测试很难阅读(并且,我怀疑,更难解决)。

通过结构,我的意思是您的代码正在检查一堆三元组,并且索引似乎相隔1、2、3或4。但是这种模式已经被抽象出来,并减少到了无意义的数字。

@bereal的建议将索引拉入显式列表的建议很难更好。如果这些索引比仅仅在列表中的位置具有更多的含义,我只想添加一个常量(或一个enum子类)以说明每个索引(或每个三元组的起点)的含义。