我想知道下面是否有更短的编写代码的方式。
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]):
但是它不起作用。
答案 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
子类)以说明每个索引(或每个三元组的起点)的含义。