简体   繁体   中英

Is there a shorter way of writing this code?

I'd wanna know if there's any shorter way of writing the code below.

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:

I've already tried this:

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:

And this:

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]):

But it's not working.

If I understand correct, you're checking if any of the sub-lists with pre-definded indices consists of the value g . First you can extract the indices groups:

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

Then check them in a loop:

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

If you actually need to check all the triples, you can use itertools.combinations instead of hard-coding the indices:

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

The problem with your modified if -tests

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

is that you want to combine the truth-value of the tests, but what this code does is and your 3 values together, throwing away 2 of them. This conversion happens before the == . If the first 3 elements of l are 1, 3, 5 then the result of your and expression will be 5, and so that is what will be compared with g (and not some superposition of 1, 3 and 5 that you can then use with == ).

Your code does rather look as though there is a structure to the data that you have reduced to a flat list, and because the data no longer reflects its intention, the if -test is hard to read (and, I suspect, even harder to get right).

By structure , I mean that your code is checking a bunch of triplets and the indexes appear to be 1, 2, 3 or 4 apart. But that pattern has been abstracted out and reduced to meaningless numbers.

@bereal's suggestion to pull out the indexes into an explicit list is hard to better. I would only add, if these indexes have more meaning than simply position in the list, consider creating constants (or an enum subclass) to say what each index (or the starting point of each triplet) means.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM